Throw exceptions when setting odd values for picture active area.
[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 ReelFileAsset;
65 class Reel;
66 class MXFMetadata;
67 class CertificateChain;
68 class DecryptedKDM;
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 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 an CompositonPlaylist XML file
123          *
124          *  @param file Filename to write
125          *  @param signer Signer to sign the CPL, or 0 to add no signature
126          */
127         void write_xml (
128                 boost::filesystem::path file,
129                 std::shared_ptr<const CertificateChain>
130                 ) const;
131
132         void resolve_refs (std::vector<std::shared_ptr<Asset>>);
133
134         int64_t duration () const;
135
136         std::string issuer () const {
137                 return _issuer;
138         }
139
140         void set_issuer (std::string issuer) {
141                 _issuer = issuer;
142         }
143
144         std::string creator () const {
145                 return _creator;
146         }
147
148         void set_creator (std::string creator) {
149                 _creator = creator;
150         }
151
152         void set_issue_date (std::string issue_date) {
153                 _issue_date = issue_date;
154         }
155
156         /** @return contents of the &lt;AnnotationText&gt; node, if present */
157         boost::optional<std::string> annotation_text () const {
158                 return _annotation_text;
159         }
160
161         void set_annotation_text (std::string at) {
162                 _annotation_text = at;
163         }
164
165         /** @return contents of the &lt;ContentTitleText&gt; node */
166         std::string content_title_text () const {
167                 return _content_title_text;
168         }
169
170         void set_content_title_text (std::string ct) {
171                 _content_title_text = ct;
172         }
173
174         void set_content_kind (dcp::ContentKind k) {
175                 _content_kind = k;
176         }
177
178         /** @return the type of the content, used by media servers
179          *  to categorise things (e.g. feature, trailer, etc.)
180          */
181         ContentKind content_kind () const {
182                 return _content_kind;
183         }
184
185         boost::optional<ContentVersion> content_version () const;
186
187         std::vector<ContentVersion> content_versions () const {
188                 return _content_versions;
189         }
190
191         void set_content_version (ContentVersion v) {
192                 _content_versions.clear ();
193                 _content_versions.push_back (v);
194         }
195
196         void set_content_versions (std::vector<ContentVersion> v);
197
198         std::vector<Rating> ratings () const {
199                 return _ratings;
200         }
201
202         void set_ratings (std::vector<Rating> r) {
203                 _ratings = r;
204         }
205
206         boost::optional<std::string> full_content_title_text () const {
207                 return _full_content_title_text;
208         }
209
210         void set_full_content_title_text (std::string t) {
211                 _full_content_title_text = t;
212         }
213
214         boost::optional<std::string> full_content_title_text_language () const {
215                 return _full_content_title_text_language;
216         }
217
218         void set_full_content_title_text_language (dcp::LanguageTag l) {
219                 _full_content_title_text_language = l.to_string();
220         }
221
222         boost::optional<std::string> release_territory () const {
223                 return _release_territory;
224         }
225
226         void set_release_territory (dcp::LanguageTag::RegionSubtag t) {
227                 _release_territory = t.subtag();
228         }
229
230         boost::optional<std::string> release_territory_scope () const {
231                 return _release_territory_scope;
232         }
233
234         boost::optional<int> version_number () const {
235                 return _version_number;
236         }
237
238         void set_version_number (int v);
239
240         void unset_version_number ();
241
242         boost::optional<Status> status () const {
243                 return _status;
244         }
245
246         void set_status (Status s) {
247                 _status = s;
248         }
249
250         boost::optional<std::string> chain () const {
251                 return _chain;
252         }
253
254         void set_chain (std::string c) {
255                 _chain = c;
256         }
257
258         boost::optional<std::string> distributor () const {
259                 return _distributor;
260         }
261
262         void set_distributor (std::string d) {
263                 _distributor = d;
264         }
265
266         boost::optional<std::string> facility () const {
267                 return _facility;
268         }
269
270         void set_facility (std::string f) {
271                 _facility = f;
272         }
273
274         boost::optional<Luminance> luminance () const {
275                 return _luminance;
276         }
277
278         void set_luminance (Luminance l) {
279                 _luminance = l;
280         }
281
282         boost::optional<std::string> main_sound_configuration () const {
283                 return _main_sound_configuration;
284         }
285
286         void set_main_sound_configuration (std::string c) {
287                 _main_sound_configuration = c;
288         }
289
290         boost::optional<int> main_sound_sample_rate () const {
291                 return _main_sound_sample_rate;
292         }
293
294         void set_main_sound_sample_rate (int r) {
295                 _main_sound_sample_rate = r;
296         }
297
298         boost::optional<dcp::Size> main_picture_stored_area () const {
299                 return _main_picture_stored_area;
300         }
301
302         void set_main_picture_stored_area (dcp::Size s) {
303                 _main_picture_stored_area = s;
304         }
305
306         boost::optional<dcp::Size> main_picture_active_area () const {
307                 return _main_picture_active_area;
308         }
309
310         void set_main_picture_active_area(dcp::Size area);
311
312         std::vector<std::string> additional_subtitle_languages () const {
313                 return _additional_subtitle_languages;
314         }
315
316         void set_additional_subtitle_languages (std::vector<dcp::LanguageTag> const& lang);
317
318         void set_sign_language_video_language (dcp::LanguageTag lang) {
319                 _sign_language_video_language = lang.to_string();
320         }
321
322         boost::optional<std::string> sign_language_video_language () const {
323                 return _sign_language_video_language;
324         }
325
326         Standard standard () const {
327                 return _standard;
328         }
329
330         /** @return true iff this CPL was read from a file and it contained
331          *  a CompositionMetadataAsset node.
332          */
333         bool read_composition_metadata() const {
334                 return _read_composition_metadata;
335         }
336
337         static std::string static_pkl_type (Standard standard);
338
339 protected:
340         /** @return type string for PKLs for this asset */
341         std::string pkl_type (Standard standard) const override;
342
343 private:
344         friend struct ::verify_invalid_language3;
345
346         void maybe_write_composition_metadata_asset (xmlpp::Element* node) const;
347         void read_composition_metadata_asset (cxml::ConstNodePtr node);
348
349         std::string _issuer;
350         std::string _creator;
351         std::string _issue_date;
352         boost::optional<std::string> _annotation_text;
353         std::string _content_title_text;            ///< &lt;ContentTitleText&gt;
354         ContentKind _content_kind;                  ///< &lt;ContentKind&gt;
355         std::vector<ContentVersion> _content_versions;
356         std::vector<Rating> _ratings;
357         /** ID for CompositionMetadataAsset tag; either a random one, ready for writing a new tag,
358          *  or the one read in from the existing CPL.
359          */
360         std::string _cpl_metadata_id = make_uuid();
361         /** Human-readable name of the composition, without any metadata (i.e. no -FTR-EN-XX- etc.) */
362         boost::optional<std::string> _full_content_title_text;
363         boost::optional<std::string> _full_content_title_text_language;
364         /** This is stored and returned as a string so that we can tolerate non-RFC-5646 strings,
365          *  but must be set as a dcp::LanguageTag to try to ensure that we create compliant output.
366          */
367         boost::optional<std::string> _release_territory;
368         boost::optional<std::string> _release_territory_scope;
369         boost::optional<int> _version_number;
370         boost::optional<Status> _status;
371         boost::optional<std::string> _chain;
372         boost::optional<std::string> _distributor;
373         boost::optional<std::string> _facility;
374         boost::optional<Luminance> _luminance;
375         boost::optional<std::string> _main_sound_configuration;
376         boost::optional<int> _main_sound_sample_rate;
377         boost::optional<dcp::Size> _main_picture_stored_area;
378         boost::optional<dcp::Size> _main_picture_active_area;
379         /* See note for _release_territory above */
380         std::vector<std::string> _additional_subtitle_languages;
381         boost::optional<std::string> _sign_language_video_language;
382         bool _read_composition_metadata = false;
383
384         std::vector<std::shared_ptr<Reel>> _reels;
385
386         /** Standard of CPL that was read in */
387         Standard _standard;
388 };
389
390
391 }
392
393
394 #endif