2a2fc827e3acaac6eed0f8e530e9ce666af1d173
[libdcp.git] / src / cpl.h
1 /*
2     Copyright (C) 2014-2021 Carl Hetherington <cth@carlh.net>
3
4     This file is part of libdcp.
5
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.
10
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.
15
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/>.
18
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
23     including the two.
24
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.
32 */
33
34
35 /** @file  src/cpl.h
36  *  @brief CPL class
37  */
38
39
40 #ifndef LIBDCP_CPL_H
41 #define LIBDCP_CPL_H
42
43
44 #include "asset.h"
45 #include "certificate.h"
46 #include "content_kind.h"
47 #include "key.h"
48 #include "language_tag.h"
49 #include "rating.h"
50 #include "types.h"
51 #include <boost/filesystem.hpp>
52 #include <boost/function.hpp>
53 #include <boost/optional.hpp>
54 #include <memory>
55 #include <vector>
56
57
58 struct verify_invalid_language3;
59
60
61 namespace dcp {
62
63
64 class CertificateChain;
65 class DecryptedKDM;
66 class MXFMetadata;
67 class Reel;
68 class ReelFileAsset;
69 class SoundAsset;
70
71
72 /** @class CPL
73  *  @brief A Composition Playlist
74  *
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.
77  *
78  *  After creating a CPL you can add Reel objects with add(), and write an XML file describing the CPL with
79  *  write_xml().
80  */
81 class CPL : public Asset
82 {
83 public:
84         CPL (std::string annotation_text, ContentKind content_kind, Standard standard);
85
86         /** Construct a CPL object from a XML file */
87         explicit CPL (boost::filesystem::path file);
88
89         bool equals (
90                 std::shared_ptr<const Asset> other,
91                 EqualityOptions const& options,
92                 NoteHandler note
93                 ) const override;
94
95         /** Add a reel to this CPL
96          *  @param reel Reel to add
97          */
98         void add (std::shared_ptr<Reel> reel);
99
100         void set (std::vector<std::shared_ptr<Reel>> reels);
101
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.
104          *  @param kdm KDM.
105          */
106         void add (DecryptedKDM const &);
107
108         /** @return the reels in this CPL */
109         std::vector<std::shared_ptr<Reel>> reels () const {
110                 return _reels;
111         }
112
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 ();
116
117         /** @return true if we have any encrypted content */
118         bool any_encrypted () const;
119
120         /** @return true if we have all our encryptable content is encrypted */
121         bool all_encrypted () const;
122
123         /** Write a CompositionPlaylist XML file
124          *
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,
128          *  false to omit it.
129          */
130         void write_xml (
131                 boost::filesystem::path file,
132                 std::shared_ptr<const CertificateChain>,
133                 bool include_mca_subdescriptors = true
134                 ) const;
135
136         void resolve_refs (std::vector<std::shared_ptr<Asset>>);
137
138         int64_t duration () const;
139
140         std::string issuer () const {
141                 return _issuer;
142         }
143
144         void set_issuer (std::string issuer) {
145                 _issuer = issuer;
146         }
147
148         std::string creator () const {
149                 return _creator;
150         }
151
152         void set_creator (std::string creator) {
153                 _creator = creator;
154         }
155
156         void set_issue_date (std::string issue_date) {
157                 _issue_date = issue_date;
158         }
159
160         /** @return contents of the &lt;AnnotationText&gt; node, if present */
161         boost::optional<std::string> annotation_text () const {
162                 return _annotation_text;
163         }
164
165         void set_annotation_text (std::string at) {
166                 _annotation_text = at;
167         }
168
169         /** @return contents of the &lt;ContentTitleText&gt; node */
170         std::string content_title_text () const {
171                 return _content_title_text;
172         }
173
174         void set_content_title_text (std::string ct) {
175                 _content_title_text = ct;
176         }
177
178         void set_content_kind (dcp::ContentKind k) {
179                 _content_kind = k;
180         }
181
182         /** @return the type of the content, used by media servers
183          *  to categorise things (e.g. feature, trailer, etc.)
184          */
185         ContentKind content_kind () const {
186                 return _content_kind;
187         }
188
189         boost::optional<ContentVersion> content_version () const;
190
191         std::vector<ContentVersion> content_versions () const {
192                 return _content_versions;
193         }
194
195         void set_content_version (ContentVersion v) {
196                 _content_versions.clear ();
197                 _content_versions.push_back (v);
198         }
199
200         void set_content_versions (std::vector<ContentVersion> v);
201
202         std::vector<Rating> ratings () const {
203                 return _ratings;
204         }
205
206         void set_ratings (std::vector<Rating> r) {
207                 _ratings = r;
208         }
209
210         boost::optional<std::string> full_content_title_text () const {
211                 return _full_content_title_text;
212         }
213
214         void set_full_content_title_text (std::string t) {
215                 _full_content_title_text = t;
216         }
217
218         boost::optional<std::string> full_content_title_text_language () const {
219                 return _full_content_title_text_language;
220         }
221
222         void set_full_content_title_text_language (dcp::LanguageTag l) {
223                 _full_content_title_text_language = l.to_string();
224         }
225
226         boost::optional<std::string> release_territory () const {
227                 return _release_territory;
228         }
229
230         void set_release_territory (dcp::LanguageTag::RegionSubtag t) {
231                 _release_territory = t.subtag();
232         }
233
234         boost::optional<std::string> release_territory_scope () const {
235                 return _release_territory_scope;
236         }
237
238         boost::optional<int> version_number () const {
239                 return _version_number;
240         }
241
242         void set_version_number (int v);
243
244         void unset_version_number ();
245
246         boost::optional<Status> status () const {
247                 return _status;
248         }
249
250         void set_status (Status s) {
251                 _status = s;
252         }
253
254         boost::optional<std::string> chain () const {
255                 return _chain;
256         }
257
258         void set_chain (std::string c) {
259                 _chain = c;
260         }
261
262         boost::optional<std::string> distributor () const {
263                 return _distributor;
264         }
265
266         void set_distributor (std::string d) {
267                 _distributor = d;
268         }
269
270         boost::optional<std::string> facility () const {
271                 return _facility;
272         }
273
274         void set_facility (std::string f) {
275                 _facility = f;
276         }
277
278         boost::optional<Luminance> luminance () const {
279                 return _luminance;
280         }
281
282         void set_luminance (Luminance l) {
283                 _luminance = l;
284         }
285
286         boost::optional<dcp::MainSoundConfiguration> main_sound_configuration () const {
287                 return _main_sound_configuration;
288         }
289
290         void set_main_sound_configuration(dcp::MainSoundConfiguration c) {
291                 _main_sound_configuration = c;
292         }
293
294         boost::optional<int> main_sound_sample_rate () const {
295                 return _main_sound_sample_rate;
296         }
297
298         void set_main_sound_sample_rate (int r) {
299                 _main_sound_sample_rate = r;
300         }
301
302         boost::optional<dcp::Size> main_picture_stored_area () const {
303                 return _main_picture_stored_area;
304         }
305
306         void set_main_picture_stored_area (dcp::Size s) {
307                 _main_picture_stored_area = s;
308         }
309
310         boost::optional<dcp::Size> main_picture_active_area () const {
311                 return _main_picture_active_area;
312         }
313
314         void set_main_picture_active_area(dcp::Size area);
315
316         std::vector<std::string> additional_subtitle_languages () const {
317                 return _additional_subtitle_languages;
318         }
319
320         void set_additional_subtitle_languages (std::vector<dcp::LanguageTag> const& lang);
321
322         void set_sign_language_video_language (dcp::LanguageTag lang) {
323                 _sign_language_video_language = lang.to_string();
324         }
325
326         boost::optional<std::string> sign_language_video_language () const {
327                 return _sign_language_video_language;
328         }
329
330         Standard standard () const {
331                 return _standard;
332         }
333
334         /** @return true iff this CPL was read from a file and it contained
335          *  a CompositionMetadataAsset node.
336          */
337         bool read_composition_metadata() const {
338                 return _read_composition_metadata;
339         }
340
341         static std::string static_pkl_type (Standard standard);
342
343 protected:
344         /** @return type string for PKLs for this asset */
345         std::string pkl_type (Standard standard) const override;
346
347 private:
348         friend struct ::verify_invalid_language3;
349
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;
353
354         std::string _issuer;
355         std::string _creator;
356         std::string _issue_date;
357         boost::optional<std::string> _annotation_text;
358         std::string _content_title_text;            ///< &lt;ContentTitleText&gt;
359         ContentKind _content_kind;                  ///< &lt;ContentKind&gt;
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.
364          */
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.
371          */
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;
388
389         std::vector<std::shared_ptr<Reel>> _reels;
390
391         /** Standard of CPL that was read in */
392         Standard _standard;
393 };
394
395
396 }
397
398
399 #endif