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