/* Copyright (C) 2013 Carl Hetherington This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include "asset_instance.h" #include "exceptions.h" using std::bad_cast; using std::make_pair; using std::pair; using std::string; using boost::shared_ptr; using boost::lexical_cast; using boost::dynamic_pointer_cast; using namespace libdcp; #define EQUALS_CHECK(param, what) if (param != other->param) { note (ERROR, what " differ"); return false; } AssetInstance::AssetInstance (shared_ptr node) { id = node->string_child ("Id"); annotation_text = node->optional_string_child ("AnnotationText").get_value_or (""); edit_rate = Fraction (node->string_child ("EditRate")); intrinsic_duration = node->number_child ("IntrinsicDuration"); entry_point = node->number_child ("EntryPoint"); duration = node->number_child ("Duration"); key_id = node->optional_string_child ("KeyId").get_value_or (""); node->ignore_child ("Hash"); node->ignore_child ("Language"); node->done (); } void AssetInstance::write_to_cpl (xmlpp::Node* node, bool interop) const { pair const attr = cpl_node_attribute (interop); xmlpp::Element* a = node->add_child (cpl_node_name ()); if (!attr.first.empty ()) { a->set_attribute (attr.first, attr.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 (lexical_cast (edit_rate.numerator) + " 1"); a->add_child ("IntrinsicDuration")->add_child_text (lexical_cast (intrinsic_duration)); a->add_child ("EntryPoint")->add_child_text (lexical_cast (entry_point)); a->add_child ("Duration")->add_child_text (lexical_cast (duration)); if (!key_id.empty ()) { a->add_child("KeyId")->add_child_text ("urn:uuid:" + key_id); } } bool AssetInstance::equals (shared_ptr other, EqualityOptions, boost::function note) const { EQUALS_CHECK (cpl_node_name(), "CPL asset types"); EQUALS_CHECK (id, "CPL asset ids"); EQUALS_CHECK (annotation_text, "CPL asset annotation texts"); EQUALS_CHECK (edit_rate, "CPL asset edit rates"); EQUALS_CHECK (intrinsic_duration, "CPL asset intrinsic durations"); EQUALS_CHECK (entry_point, "CPL asset entry points"); EQUALS_CHECK (duration, "CPL asset durations"); EQUALS_CHECK (key_id, "CPL asset key ids"); return true; } Picture::Picture (shared_ptr node) : AssetInstance (node) { frame_rate = Fraction (node->string_child ("FrameRate")); try { screen_aspect_ratio = Fraction (node->string_child ("ScreenAspectRatio")); } catch (XMLError& e) { /* Maybe it's not a fraction */ } try { float f = node->number_child ("ScreenAspectRatio"); screen_aspect_ratio = Fraction (f * 1000, 1000); } catch (bad_cast& e) { } } void Picture::write_to_cpl (xmlpp::Node* node, bool interop) const { AssetInstance::write_to_cpl (node, interop); xmlpp::Node::NodeList c = node->get_children (); xmlpp::Node::NodeList::iterator i = c.begin(); while (i != c.end() && (*i)->get_name() != cpl_node_name ()) { ++i; } assert (i != c.end ()); (*i)->add_child ("FrameRate")->add_child_text (lexical_cast (frame_rate.numerator + " " + frame_rate.denominator)); if (interop) { (*i)->add_child ("ScreenAspectRatio")->add_child_text ( lexical_cast (float (screen_aspect_ratio.numerator) / screen_aspect_ratio.denominator) ); } else { (*i)->add_child ("ScreenAspectRatio")->add_child_text ( lexical_cast (screen_aspect_ratio.numerator) + " " + lexical_cast (screen_aspect_ratio.denominator) ); } } bool Picture::equals (shared_ptr other, EqualityOptions, boost::function note) const { shared_ptr p = dynamic_pointer_cast (other); if (!p) { note (ERROR, "CPL assets differ in type"); return false; } if (frame_rate != p->frame_rate) { note (ERROR, "CPL asset frame rates differ"); return false; } if (screen_aspect_ratio != p->screen_aspect_ratio) { note (ERROR, "CPL screen aspect ratios differ"); return false; } return true; } pair MainStereoscopicPicture::cpl_node_attribute (bool interop) const { if (interop) { return make_pair ("xmlns:msp-cpl", "http://www.digicine.com/schemas/437-Y/2007/Main-Stereo-Picture-CPL"); } else { return make_pair ("xmlns:msp-cpl", "http://www.smpte-ra.org/schemas/429-10/2008/Main-Stereo-Picture-CPL"); } return make_pair ("", ""); }