summaryrefslogtreecommitdiff
path: root/src/reel.cc
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2024-06-26 01:30:41 +0200
committerCarl Hetherington <cth@carlh.net>2024-06-26 01:30:41 +0200
commit632fd6b46be907c044474a09ffffad6cccb14d08 (patch)
tree668cb6f45ed1d549b1298193c7b66a28bb9c19f2 /src/reel.cc
parente85519d4085b6af00f0c407b65f3cccd5c7ddcf1 (diff)
fixup! Collect MainCaption and ClosedSubtitle assets and use the correct tags for them.
Diffstat (limited to 'src/reel.cc')
-rw-r--r--src/reel.cc200
1 files changed, 153 insertions, 47 deletions
diff --git a/src/reel.cc b/src/reel.cc
index 4e560157..c4e3fbbc 100644
--- a/src/reel.cc
+++ b/src/reel.cc
@@ -37,6 +37,7 @@
*/
+#include "compose.hpp"
#include "decrypted_kdm.h"
#include "decrypted_kdm_key.h"
#include "equality_options.h"
@@ -211,37 +212,19 @@ Reel::write_to_cpl (xmlpp::Element* node, Standard standard) const
}
-bool
-Reel::equals(std::shared_ptr<const Reel> other, EqualityOptions const& opt, NoteHandler note) const
+template <class Parent, class Interop, class SMPTE>
+bool text_equals(string name, Reel const* this_reel, Reel const* other_reel, std::function<shared_ptr<Parent> (Reel const* reel)> get, EqualityOptions const& opt, NoteHandler note)
{
- if ((_main_picture && !other->_main_picture) || (!_main_picture && other->_main_picture)) {
- note (NoteType::ERROR, "Reel: picture assets differ");
- return false;
- }
-
- if (_main_picture && !_main_picture->equals (other->_main_picture, opt, note)) {
- return false;
- }
-
- if ((_main_sound && !other->_main_sound) || (!_main_sound && other->_main_sound)) {
- note (NoteType::ERROR, "Reel: sound assets differ");
- return false;
- }
-
- if (_main_sound && !_main_sound->equals (other->_main_sound, opt, note)) {
- return false;
- }
-
- if ((_main_subtitle && !other->_main_subtitle) || (!_main_subtitle && other->_main_subtitle)) {
- note (NoteType::ERROR, "Reel: subtitle assets differ");
+ if ((get(this_reel) && !get(other_reel)) || (!get(this_reel) && get(other_reel))) {
+ note(NoteType::ERROR, String::compose("Reel: %1 assets differ", name));
return false;
}
bool same_type = false;
{
- auto interop = dynamic_pointer_cast<ReelInteropSubtitleAsset>(_main_subtitle);
- auto interop_other = dynamic_pointer_cast<ReelInteropSubtitleAsset>(other->_main_subtitle);
+ auto interop = dynamic_pointer_cast<Interop>(get(this_reel));
+ auto interop_other = dynamic_pointer_cast<Interop>(get(other_reel));
if (interop && interop_other) {
same_type = true;
if (!interop->equals(interop_other, opt, note)) {
@@ -251,8 +234,8 @@ Reel::equals(std::shared_ptr<const Reel> other, EqualityOptions const& opt, Note
}
{
- auto smpte = dynamic_pointer_cast<ReelSMPTESubtitleAsset>(_main_subtitle);
- auto smpte_other = dynamic_pointer_cast<ReelSMPTESubtitleAsset>(other->_main_subtitle);
+ auto smpte = dynamic_pointer_cast<SMPTE>(get(this_reel));
+ auto smpte_other = dynamic_pointer_cast<SMPTE>(get(other_reel));
if (smpte && smpte_other) {
same_type = true;
if (!smpte->equals(smpte_other, opt, note)) {
@@ -261,7 +244,50 @@ Reel::equals(std::shared_ptr<const Reel> other, EqualityOptions const& opt, Note
}
}
- if ((_main_subtitle || other->_main_subtitle) && !same_type) {
+ if ((get(this_reel) || get(other_reel)) && !same_type) {
+ return false;
+ }
+
+ return true;
+}
+
+
+bool
+Reel::equals(std::shared_ptr<const Reel> other, EqualityOptions const& opt, NoteHandler note) const
+{
+ if ((_main_picture && !other->_main_picture) || (!_main_picture && other->_main_picture)) {
+ note (NoteType::ERROR, "Reel: picture assets differ");
+ return false;
+ }
+
+ if (_main_picture && !_main_picture->equals (other->_main_picture, opt, note)) {
+ return false;
+ }
+
+ if ((_main_sound && !other->_main_sound) || (!_main_sound && other->_main_sound)) {
+ note (NoteType::ERROR, "Reel: sound assets differ");
+ return false;
+ }
+
+ if (_main_sound && !_main_sound->equals (other->_main_sound, opt, note)) {
+ return false;
+ }
+
+ if (!text_equals<ReelSubtitleAsset, ReelInteropSubtitleAsset, ReelSMPTESubtitleAsset>(
+ "subtitle",
+ this,
+ other.get(),
+ [](Reel const* reel) { return reel->_main_subtitle; }, opt, note)
+ ) {
+ return false;
+ }
+
+ if (!text_equals<ReelCaptionAsset, ReelInteropCaptionAsset, ReelSMPTECaptionAsset>(
+ "caption",
+ this,
+ other.get(),
+ [](Reel const* reel) { return reel->_main_caption; }, opt, note)
+ ) {
return false;
}
@@ -275,18 +301,36 @@ Reel::equals(std::shared_ptr<const Reel> other, EqualityOptions const& opt, Note
return false;
}
- if (_closed_captions.size() != other->_closed_captions.size()) {
- return false;
- }
+ {
+ if (_closed_subtitles.size() != other->_closed_subtitles.size()) {
+ return false;
+ }
+
+ auto i = _closed_subtitles.begin();
+ auto j = other->_closed_subtitles.begin();
+ while (i != _closed_subtitles.end()) {
+ if (!(*i)->equals(*j, opt, note)) {
+ return false;
+ }
+ ++i;
+ ++j;
+ }
- auto i = _closed_captions.begin();
- auto j = other->_closed_captions.begin();
- while (i != _closed_captions.end()) {
- if (!(*i)->equals(*j, opt, note)) {
+ if (_closed_captions.size() != other->_closed_captions.size()) {
return false;
}
- ++i;
- ++j;
+ }
+
+ {
+ auto i = _closed_captions.begin();
+ auto 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)) {
@@ -306,16 +350,20 @@ bool
Reel::any_encrypted () const
{
auto ecc = false;
- for (auto i: _closed_captions) {
- if (i->encrypted()) {
- ecc = true;
- }
+
+ if (std::find_if(_closed_subtitles.begin(), _closed_subtitles.end(), [](shared_ptr<ReelSubtitleAsset> asset) { return asset->encrypted(); }) != _closed_subtitles.end()) {
+ ecc = true;
+ }
+
+ if (std::find_if(_closed_captions.begin(), _closed_captions.end(), [](shared_ptr<ReelCaptionAsset> asset) { return asset->encrypted(); }) != _closed_captions.end()) {
+ ecc = true;
}
return (
(_main_picture && _main_picture->encrypted()) ||
(_main_sound && _main_sound->encrypted()) ||
(_main_subtitle && _main_subtitle->encrypted()) ||
+ (_main_caption && _main_caption->encrypted()) ||
ecc ||
(_atmos && _atmos->encrypted())
);
@@ -326,16 +374,20 @@ bool
Reel::all_encrypted () const
{
auto ecc = true;
- for (auto i: _closed_captions) {
- if (!i->encrypted()) {
- ecc = false;
- }
+
+ if (std::find_if(_closed_subtitles.begin(), _closed_subtitles.end(), [](shared_ptr<ReelSubtitleAsset> asset) { return !asset->encrypted(); }) != _closed_subtitles.end()) {
+ ecc = false;
+ }
+
+ if (std::find_if(_closed_captions.begin(), _closed_captions.end(), [](shared_ptr<ReelCaptionAsset> asset) { return !asset->encrypted(); }) != _closed_captions.end()) {
+ ecc = false;
}
return (
(!_main_picture || _main_picture->encrypted()) &&
(!_main_sound || _main_sound->encrypted()) &&
(!_main_subtitle || _main_subtitle->encrypted()) &&
+ (!_main_caption || _main_caption->encrypted()) &&
ecc &&
(!_atmos || _atmos->encrypted())
);
@@ -370,12 +422,24 @@ Reel::give_kdm_to_assets (DecryptedKDM const & kdm)
smpte->smpte_asset()->set_key(i.key());
}
}
- for (auto j: _closed_captions) {
+ if (_main_caption) {
+ auto smpte = dynamic_pointer_cast<ReelSMPTECaptionAsset>(_main_caption);
+ if (smpte && i.id() == smpte->key_id() && smpte->asset_ref().resolved()) {
+ smpte->smpte_asset()->set_key(i.key());
+ }
+ }
+ for (auto j: _closed_subtitles) {
auto smpte = dynamic_pointer_cast<ReelSMPTESubtitleAsset>(j);
if (smpte && i.id() == smpte->key_id() && smpte->asset_ref().resolved()) {
smpte->smpte_asset()->set_key(i.key());
}
}
+ for (auto j: _closed_captions) {
+ auto smpte = dynamic_pointer_cast<ReelSMPTECaptionAsset>(j);
+ if (smpte && i.id() == smpte->key_id() && smpte->asset_ref().resolved()) {
+ smpte->smpte_asset()->set_key(i.key());
+ }
+ }
if (_atmos && i.id() == _atmos->key_id() && _atmos->asset_ref().resolved()) {
_atmos->asset()->set_key (i.key());
}
@@ -391,11 +455,19 @@ Reel::add (shared_ptr<ReelAsset> asset)
} else if (auto so = dynamic_pointer_cast<ReelSoundAsset>(asset)) {
_main_sound = so;
} else if (auto su = dynamic_pointer_cast<ReelSubtitleAsset>(asset)) {
- _main_subtitle = su;
+ if (su->type() == TextType::OPEN) {
+ _main_subtitle = su;
+ } else {
+ _closed_subtitles.push_back(su);
+ }
} else if (auto m = dynamic_pointer_cast<ReelMarkersAsset>(asset)) {
_main_markers = m;
} else if (auto c = dynamic_pointer_cast<ReelCaptionAsset>(asset)) {
- _closed_captions.push_back (c);
+ if (c->type() == TextType::CLOSED) {
+ _closed_captions.push_back(c);
+ } else {
+ _main_caption = c;
+ }
} else if (auto a = dynamic_pointer_cast<ReelAtmosAsset>(asset)) {
_atmos = a;
} else {
@@ -417,6 +489,10 @@ Reel::assets () const
if (_main_subtitle) {
a.push_back (_main_subtitle);
}
+ if (_main_caption) {
+ a.push_back(_main_caption);
+ }
+ std::copy(_closed_subtitles.begin(), _closed_subtitles.end(), back_inserter(a));
std::copy (_closed_captions.begin(), _closed_captions.end(), back_inserter(a));
if (_atmos) {
a.push_back (_atmos);
@@ -448,6 +524,30 @@ Reel::resolve_refs (vector<shared_ptr<Asset>> assets)
}
}
+ if (_main_caption) {
+ _main_caption->asset_ref().resolve(assets);
+
+ /* Interop caption handling is all special cases */
+ if (_main_caption->asset_ref().resolved()) {
+ auto iop = dynamic_pointer_cast<InteropSubtitleAsset>(_main_caption->asset_ref().asset());
+ if (iop) {
+ iop->resolve_fonts (assets);
+ }
+ }
+ }
+
+ for (auto i: _closed_subtitles) {
+ i->asset_ref().resolve(assets);
+
+ /* Interop subtitle handling is all special cases */
+ if (i->asset_ref().resolved()) {
+ auto iop = dynamic_pointer_cast<InteropSubtitleAsset>(i->asset_ref().asset());
+ if (iop) {
+ iop->resolve_fonts (assets);
+ }
+ }
+ }
+
for (auto i: _closed_captions) {
i->asset_ref().resolve(assets);
@@ -485,9 +585,15 @@ Reel::duration () const
if (_main_subtitle) {
d = min (d, _main_subtitle->actual_duration());
}
+ if (_main_caption) {
+ d = min(d, _main_caption->actual_duration());
+ }
if (_main_markers) {
d = min (d, _main_markers->actual_duration());
}
+ for (auto i: _closed_subtitles) {
+ d = min (d, i->actual_duration());
+ }
for (auto i: _closed_captions) {
d = min (d, i->actual_duration());
}