X-Git-Url: https://git.carlh.net/gitweb/?a=blobdiff_plain;f=src%2Freel_asset.cc;h=5b8f3126b5f01a97a18133a36a1ee6581d9e8a94;hb=a1e7f77e8fcfd71cc8bf94d13ceb2decbacc3b50;hp=caaf3eee45fc14ca6f560899840c1f5ac89aa239;hpb=4946acfd735321e7f0c29ea4b6e371bc9e90a7f6;p=libdcp.git diff --git a/src/reel_asset.cc b/src/reel_asset.cc index caaf3eee..5b8f3126 100644 --- a/src/reel_asset.cc +++ b/src/reel_asset.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2014-2015 Carl Hetherington + Copyright (C) 2014-2022 Carl Hetherington This file is part of libdcp. @@ -31,119 +31,166 @@ files in the program, then also delete it here. */ + /** @file src/reel_asset.cc - * @brief ReelAsset class. + * @brief ReelAsset class */ -#include "raw_convert.h" -#include "reel_asset.h" + #include "asset.h" #include "compose.hpp" +#include "dcp_assert.h" +#include "raw_convert.h" +#include "reel_asset.h" +#include "warnings.h" #include +LIBDCP_DISABLE_WARNINGS #include +LIBDCP_ENABLE_WARNINGS + +using std::make_pair; using std::pair; +using std::shared_ptr; using std::string; -using std::make_pair; -using boost::shared_ptr; using boost::optional; using namespace dcp; -/** Construct a ReelAsset. - * @param id ID of this ReelAsset (which is that of the MXF, if there is one) - * @param edit_rate Edit rate for the asset. - * @param intrinsic_duration Intrinsic duration of this asset. - * @param entry_point Entry point to use in that asset. - */ -ReelAsset::ReelAsset (string id, Fraction edit_rate, int64_t intrinsic_duration, int64_t entry_point) + +ReelAsset::ReelAsset (string id, Fraction edit_rate, int64_t intrinsic_duration, optional entry_point) : Object (id) , _intrinsic_duration (intrinsic_duration) - , _duration (intrinsic_duration - entry_point) , _edit_rate (edit_rate) , _entry_point (entry_point) { + if (_entry_point) { + _duration = intrinsic_duration - *_entry_point; + } + DCP_ASSERT (!_entry_point || *_entry_point <= _intrinsic_duration); } + ReelAsset::ReelAsset (shared_ptr node) : Object (remove_urn_uuid (node->string_child ("Id"))) , _intrinsic_duration (node->number_child ("IntrinsicDuration")) - , _duration (node->number_child ("Duration")) - , _annotation_text (node->optional_string_child ("AnnotationText").get_value_or ("")) + , _duration (node->optional_number_child("Duration")) + , _annotation_text (node->optional_string_child("AnnotationText")) , _edit_rate (Fraction (node->string_child ("EditRate"))) - , _entry_point (node->number_child ("EntryPoint")) + , _entry_point (node->optional_number_child("EntryPoint")) { } + xmlpp::Node* -ReelAsset::write_to_cpl_base (xmlpp::Node* node, Standard standard, optional hash) const +ReelAsset::write_to_cpl (xmlpp::Node* node, Standard standard) const { - xmlpp::Element* a = node->add_child (cpl_node_name (standard)); - pair const attr = cpl_node_attribute (standard); - if (!attr.first.empty ()) { - a->set_attribute (attr.first, attr.second); - } - pair const ns = cpl_node_namespace (standard); - if (!ns.first.empty ()) { - a->set_namespace_declaration (ns.first, ns.second); - } - a->add_child("Id")->add_child_text ("urn:uuid:" + _id); - a->add_child("AnnotationText")->add_child_text (_annotation_text); - a->add_child("EditRate")->add_child_text (String::compose ("%1 %2", _edit_rate.numerator, _edit_rate.denominator)); - a->add_child("IntrinsicDuration")->add_child_text (raw_convert (_intrinsic_duration)); - a->add_child("EntryPoint")->add_child_text (raw_convert (_entry_point)); - a->add_child("Duration")->add_child_text (raw_convert (_duration)); - if (hash) { - a->add_child("Hash")->add_child_text (hash.get()); + auto a = node->add_child (cpl_node_name (standard)); + auto const attr = cpl_node_attribute (standard); + if (!attr.first.empty ()) { + a->set_attribute (attr.first, attr.second); + } + auto const ns = cpl_node_namespace (); + if (!ns.first.empty()) { + a->set_namespace_declaration (ns.first, ns.second); + } + a->add_child("Id")->add_child_text ("urn:uuid:" + _id); + /* Empty tags cause refusal to play on some Sony SRX320 / LMT3000 systems (DoM bug #2124) */ + if (_annotation_text && !_annotation_text->empty()) { + a->add_child("AnnotationText")->add_child_text(*_annotation_text); + } + a->add_child("EditRate")->add_child_text (_edit_rate.as_string()); + a->add_child("IntrinsicDuration")->add_child_text (raw_convert (_intrinsic_duration)); + if (_entry_point) { + a->add_child("EntryPoint")->add_child_text(raw_convert(*_entry_point)); + } + if (_duration) { + a->add_child("Duration")->add_child_text(raw_convert(*_duration)); } return a; } + pair ReelAsset::cpl_node_attribute (Standard) const { return make_pair ("", ""); } + pair -ReelAsset::cpl_node_namespace (Standard) const +ReelAsset::cpl_node_namespace () const { return make_pair ("", ""); } + +template +string +optional_to_string (optional o) +{ + return o ? raw_convert(*o) : "[none]"; +} + + bool -ReelAsset::asset_equals (shared_ptr other, EqualityOptions opt, NoteHandler note) const +ReelAsset::asset_equals(shared_ptr other, EqualityOptions const& opt, NoteHandler note) const { + auto const node = cpl_node_name(Standard::SMPTE); + if (_annotation_text != other->_annotation_text) { - string const s = "Reel: annotation texts differ (" + _annotation_text + " vs " + other->_annotation_text + ")\n"; + 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)); if (!opt.reel_annotation_texts_can_differ) { - note (DCP_ERROR, s); + note (NoteType::ERROR, s); return false; } else { - note (DCP_NOTE, s); + note (NoteType::NOTE, s); } } if (_edit_rate != other->_edit_rate) { - note (DCP_ERROR, "Reel: edit rates differ"); + note ( + NoteType::ERROR, + String::compose("Reel %1: edit rates differ (%2 vs %3)", node, _edit_rate.as_string(), other->_edit_rate.as_string()) + ); return false; } if (_intrinsic_duration != other->_intrinsic_duration) { - note (DCP_ERROR, String::compose ("Reel: intrinsic durations differ (%1 vs %2)", _intrinsic_duration, other->_intrinsic_duration)); + note ( + NoteType::ERROR, + String::compose("Reel %1: intrinsic durations differ (%2 vs %3)", node, _intrinsic_duration, other->_intrinsic_duration) + ); return false; } if (_entry_point != other->_entry_point) { - note (DCP_ERROR, "Reel: entry points differ"); + note ( + NoteType::ERROR, + String::compose("Reel %1: entry points differ (%2 vs %3)", node, optional_to_string(_entry_point), optional_to_string(other->_entry_point)) + ); return false; } if (_duration != other->_duration) { - note (DCP_ERROR, "Reel: durations differ"); + note ( + NoteType::ERROR, + String::compose("Reel %1: durations differ (%2 vs %3)", node, optional_to_string(_duration), optional_to_string(other->_duration)) + ); return false; } return true; } + + +int64_t +ReelAsset::actual_duration () const +{ + if (_duration) { + return *_duration; + } + + return _intrinsic_duration - _entry_point.get_value_or(0); +}