libdcp
reel_asset.cc
Go to the documentation of this file.
1 /*
2  Copyright (C) 2014-2022 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 
40 #include "asset.h"
41 #include "compose.hpp"
42 #include "dcp_assert.h"
43 #include "equality_options.h"
44 #include "raw_convert.h"
45 #include "reel_asset.h"
46 #include "warnings.h"
47 #include <libcxml/cxml.h>
48 LIBDCP_DISABLE_WARNINGS
49 #include <libxml++/libxml++.h>
50 LIBDCP_ENABLE_WARNINGS
51 
52 
53 using std::make_pair;
54 using std::pair;
55 using std::shared_ptr;
56 using std::string;
57 using boost::optional;
58 using namespace dcp;
59 
60 
61 ReelAsset::ReelAsset (string id, Fraction edit_rate, int64_t intrinsic_duration, optional<int64_t> entry_point)
62  : Object (id)
63  , _intrinsic_duration (intrinsic_duration)
64  , _edit_rate (edit_rate)
65  , _entry_point (entry_point)
66 {
67  if (_entry_point) {
68  _duration = intrinsic_duration - *_entry_point;
69  }
70 
71  DCP_ASSERT (!_entry_point || *_entry_point <= _intrinsic_duration);
72 }
73 
74 
75 ReelAsset::ReelAsset (shared_ptr<const cxml::Node> node)
76  : Object (remove_urn_uuid (node->string_child ("Id")))
77  , _intrinsic_duration (node->number_child<int64_t> ("IntrinsicDuration"))
78  , _duration (node->optional_number_child<int64_t>("Duration"))
79  , _annotation_text (node->optional_string_child("AnnotationText"))
80  , _edit_rate (Fraction (node->string_child ("EditRate")))
81  , _entry_point (node->optional_number_child<int64_t>("EntryPoint"))
82 {
83 
84 }
85 
86 
87 xmlpp::Element*
88 ReelAsset::write_to_cpl(xmlpp::Element* node, Standard standard) const
89 {
90  auto a = cxml::add_child(node, cpl_node_name());
91  auto const attr = cpl_node_attribute (standard);
92  if (!attr.first.empty ()) {
93  a->set_attribute (attr.first, attr.second);
94  }
95  auto const ns = cpl_node_namespace ();
96  if (!ns.first.empty()) {
97  a->set_namespace_declaration (ns.first, ns.second);
98  }
99  cxml::add_text_child(a, "Id", "urn:uuid:" + _id);
100  /* Empty <AnnotationText> tags cause refusal to play on some Sony SRX320 / LMT3000 systems (DoM bug #2124) */
101  if (_annotation_text && !_annotation_text->empty()) {
102  cxml::add_text_child(a, "AnnotationText", *_annotation_text);
103  }
104  cxml::add_text_child(a, "EditRate", _edit_rate.as_string());
105  cxml::add_text_child(a, "IntrinsicDuration", raw_convert<string>(_intrinsic_duration));
106  if (_entry_point) {
107  cxml::add_text_child(a, "EntryPoint", raw_convert<string>(*_entry_point));
108  }
109  if (_duration) {
110  cxml::add_text_child(a, "Duration", raw_convert<string>(*_duration));
111  }
112  return a;
113 }
114 
115 
116 pair<string, string>
118 {
119  return make_pair ("", "");
120 }
121 
122 
123 pair<string, string>
125 {
126  return make_pair ("", "");
127 }
128 
129 
130 template <class T>
131 string
132 optional_to_string (optional<T> o)
133 {
134  return o ? raw_convert<string>(*o) : "[none]";
135 }
136 
137 
138 bool
139 ReelAsset::asset_equals(shared_ptr<const ReelAsset> other, EqualityOptions const& opt, NoteHandler note) const
140 {
141  auto const node = cpl_node_name();
142 
143  if (_annotation_text != other->_annotation_text) {
144  string const s = String::compose("Reel %1: annotation texts differ (%2 vs %3)", node, optional_to_string(_annotation_text), optional_to_string(other->_annotation_text));
146  note (NoteType::ERROR, s);
147  return false;
148  } else {
149  note (NoteType::NOTE, s);
150  }
151  }
152 
153  if (_edit_rate != other->_edit_rate) {
154  note (
155  NoteType::ERROR,
156  String::compose("Reel %1: edit rates differ (%2 vs %3)", node, _edit_rate.as_string(), other->_edit_rate.as_string())
157  );
158  return false;
159  }
160 
161  if (_intrinsic_duration != other->_intrinsic_duration) {
162  note (
163  NoteType::ERROR,
164  String::compose("Reel %1: intrinsic durations differ (%2 vs %3)", node, _intrinsic_duration, other->_intrinsic_duration)
165  );
166  return false;
167  }
168 
169  if (_entry_point != other->_entry_point) {
170  note (
171  NoteType::ERROR,
172  String::compose("Reel %1: entry points differ (%2 vs %3)", node, optional_to_string(_entry_point), optional_to_string(other->_entry_point))
173  );
174  return false;
175  }
176 
177  if (_duration != other->_duration) {
178  note (
179  NoteType::ERROR,
180  String::compose("Reel %1: durations differ (%2 vs %3)", node, optional_to_string(_duration), optional_to_string(other->_duration))
181  );
182  return false;
183  }
184 
185  return true;
186 }
187 
188 
189 int64_t
191 {
192  if (_duration) {
193  return *_duration;
194  }
195 
196  return _intrinsic_duration - _entry_point.get_value_or(0);
197 }
Asset class.
A class to describe what "equality" means for a particular test.
A fraction (i.e. a thing with an integer numerator and an integer denominator).
Definition: types.h:168
Some part of a DCP that has a UUID.
Definition: object.h:63
virtual std::pair< std::string, std::string > cpl_node_attribute(Standard) const
Definition: reel_asset.cc:117
boost::optional< int64_t > _entry_point
The <EntryPoint> from the reel's entry for this asset.
Definition: reel_asset.h:156
ReelAsset(std::string id, Fraction edit_rate, int64_t intrinsic_duration, boost::optional< int64_t > entry_point)
virtual std::pair< std::string, std::string > cpl_node_namespace() const
Definition: reel_asset.cc:124
Fraction _edit_rate
The <EditRate> from the reel's entry for this asset.
Definition: reel_asset.h:155
boost::optional< std::string > _annotation_text
The <AnnotationText> from the reel's entry for this asset.
Definition: reel_asset.h:154
virtual std::string cpl_node_name() const =0
int64_t actual_duration() const
Definition: reel_asset.cc:190
int64_t _intrinsic_duration
The <IntrinsicDuration> from the reel's entry for this asset.
Definition: reel_asset.h:150
boost::optional< int64_t > _duration
The <Duration> from the reel's entry for this asset, if present.
Definition: reel_asset.h:151
DCP_ASSERT macro.
Class to describe what equality means when calling Asset::equals().
Namespace for everything in libdcp.
Definition: array_data.h:50
Methods for conversion to/from string.
ReelAsset class.