From 9f75a44df591954519ac828a1b50b6d5ebd2a3a1 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 22 Aug 2018 16:11:46 +0100 Subject: Support more than one closed caption asset per reel. --- src/cpl.cc | 4 ++-- src/reel.cc | 60 ++++++++++++++++++++++++++++++++++++++++-------------------- src/reel.h | 6 +++--- 3 files changed, 45 insertions(+), 25 deletions(-) (limited to 'src') diff --git a/src/cpl.cc b/src/cpl.cc index d23cd4aa..5108161c 100644 --- a/src/cpl.cc +++ b/src/cpl.cc @@ -185,8 +185,8 @@ CPL::reel_assets () const if (i->main_subtitle ()) { c.push_back (i->main_subtitle()); } - if (i->closed_caption ()) { - c.push_back (i->closed_caption()); + BOOST_FOREACH (shared_ptr j, i->closed_captions()) { + c.push_back (j); } if (i->atmos ()) { c.push_back (i->atmos()); diff --git a/src/reel.cc b/src/reel.cc index f8f1acb0..4b42ec0e 100644 --- a/src/reel.cc +++ b/src/reel.cc @@ -85,12 +85,13 @@ Reel::Reel (boost::shared_ptr node) } /* XXX: it's not ideal that we silently tolerate Interop or SMPTE nodes here */ - shared_ptr closed_caption = asset_list->optional_node_child ("MainClosedCaption"); - if (!closed_caption) { - closed_caption = asset_list->optional_node_child ("ClosedCaption"); + /* XXX: not sure if Interop supports multiple closed captions */ + list > closed_captions = asset_list->node_children ("MainClosedCaption"); + if (closed_captions.empty()) { + closed_captions = asset_list->node_children ("ClosedCaption"); } - if (closed_caption) { - _closed_caption.reset (new ReelClosedCaptionAsset (closed_caption)); + BOOST_FOREACH (shared_ptr i, closed_captions) { + _closed_captions.push_back (shared_ptr(new ReelClosedCaptionAsset(i))); } shared_ptr atmos = asset_list->optional_node_child ("AuxData"); @@ -122,8 +123,8 @@ Reel::write_to_cpl (xmlpp::Element* node, Standard standard) const _main_subtitle->write_to_cpl (asset_list, standard); } - if (_closed_caption) { - _closed_caption->write_to_cpl (asset_list, standard); + BOOST_FOREACH (shared_ptr i, _closed_captions) { + i->write_to_cpl (asset_list, standard); } if (_main_picture && dynamic_pointer_cast (_main_picture)) { @@ -166,10 +167,20 @@ Reel::equals (boost::shared_ptr other, EqualityOptions opt, NoteHand return false; } - if (_closed_caption && !_closed_caption->equals (other->_closed_caption, opt, note)) { + if (_closed_captions.size() != other->_closed_captions.size()) { return false; } + list >::const_iterator i = _closed_captions.begin(); + list >::const_iterator j = other->_closed_captions.begin(); + while (i != _closed_captions.end()) { + if (!(*i)->equals(*j, opt, note)) { + return false; + } + ++i; + ++j; + } + if ((_atmos && !other->_atmos) || (!_atmos && other->_atmos)) { note (DCP_ERROR, "Reel: atmos assets differ"); return false; @@ -185,11 +196,18 @@ Reel::equals (boost::shared_ptr other, EqualityOptions opt, NoteHand bool Reel::encrypted () const { + bool ecc = false; + BOOST_FOREACH (shared_ptr i, _closed_captions) { + if (i->encrypted()) { + ecc = true; + } + } + return ( (_main_picture && _main_picture->encrypted ()) || (_main_sound && _main_sound->encrypted ()) || (_main_subtitle && _main_subtitle->encrypted ()) || - (_closed_caption && _closed_caption->encrypted ()) || + ecc || (_atmos && _atmos->encrypted ()) ); } @@ -212,10 +230,12 @@ Reel::add (DecryptedKDM const & kdm) s->set_key (i->key ()); } } - if (_closed_caption && i->id() == _closed_caption->key_id()) { - shared_ptr s = dynamic_pointer_cast (_closed_caption->asset()); - if (s) { - s->set_key (i->key ()); + BOOST_FOREACH (shared_ptr j, _closed_captions) { + if (i->id() == j->key_id()) { + shared_ptr s = dynamic_pointer_cast (j->asset()); + if (s) { + s->set_key (i->key ()); + } } } if (_atmos && i->id() == _atmos->key_id()) { @@ -239,7 +259,7 @@ Reel::add (shared_ptr asset) } else if (su) { _main_subtitle = su; } else if (c) { - _closed_caption = c; + _closed_captions.push_back (c); } else if (a) { _atmos = a; } @@ -268,12 +288,12 @@ Reel::resolve_refs (list > assets) } } - if (_closed_caption) { - _closed_caption->asset_ref().resolve(assets); + BOOST_FOREACH (shared_ptr i, _closed_captions) { + i->asset_ref().resolve(assets); /* Interop subtitle handling is all special cases */ - if (_closed_caption->asset_ref().resolved()) { - shared_ptr iop = dynamic_pointer_cast (_closed_caption->asset_ref().asset()); + if (i->asset_ref().resolved()) { + shared_ptr iop = dynamic_pointer_cast (i->asset_ref().asset()); if (iop) { iop->resolve_fonts (assets); } @@ -299,8 +319,8 @@ Reel::duration () const if (_main_subtitle) { d = max (d, _main_subtitle->duration ()); } - if (_closed_caption) { - d = max (d, _closed_caption->duration ()); + BOOST_FOREACH (shared_ptr i, _closed_captions) { + d = max (d, i->duration()); } if (_atmos) { d = max (d, _atmos->duration ()); diff --git a/src/reel.h b/src/reel.h index 238ec3e0..fa37c840 100644 --- a/src/reel.h +++ b/src/reel.h @@ -92,8 +92,8 @@ public: return _main_subtitle; } - boost::shared_ptr closed_caption () const { - return _closed_caption; + std::list > closed_captions () const { + return _closed_captions; } boost::shared_ptr atmos () const { @@ -118,7 +118,7 @@ private: boost::shared_ptr _main_picture; boost::shared_ptr _main_sound; boost::shared_ptr _main_subtitle; - boost::shared_ptr _closed_caption; + std::list > _closed_captions; boost::shared_ptr _atmos; }; -- cgit v1.2.3