diff options
Diffstat (limited to 'src/mca_sub_descriptor.cc')
| -rw-r--r-- | src/mca_sub_descriptor.cc | 106 |
1 files changed, 104 insertions, 2 deletions
diff --git a/src/mca_sub_descriptor.cc b/src/mca_sub_descriptor.cc index 34bde9f8..a2341f9a 100644 --- a/src/mca_sub_descriptor.cc +++ b/src/mca_sub_descriptor.cc @@ -33,14 +33,19 @@ #include "dcp_assert.h" +#include "main_sound_configuration.h" #include "mca_sub_descriptor.h" #include "util.h" +#include <fmt/format.h> LIBDCP_DISABLE_WARNINGS #include <libxml++/libxml++.h> LIBDCP_ENABLE_WARNINGS +using std::pair; using std::string; +using std::vector; +using boost::optional; using namespace dcp; @@ -48,7 +53,7 @@ MCASubDescriptor::MCASubDescriptor(cxml::ConstNodePtr node) { tag = node->name(); instance_id = remove_urn_uuid(node->string_child("InstanceID")); - mca_label_dictionary_id = node->string_child("MCALabelDictionaryID"); + mca_label_dictionary_id = remove_urn_smpte_ul(node->string_child("MCALabelDictionaryID")); mca_link_id = remove_urn_uuid(node->string_child("MCALinkID")); mca_tag_symbol = node->string_child("MCATagSymbol"); mca_tag_name = node->optional_string_child("MCATagName"); @@ -60,12 +65,20 @@ MCASubDescriptor::MCASubDescriptor(cxml::ConstNodePtr node) } +MCASubDescriptor::MCASubDescriptor(std::string tag_) + : tag(std::move(tag_)) + , instance_id(make_uuid()) +{ + +} + + void MCASubDescriptor::as_xml(xmlpp::Element* parent) const { auto node = cxml::add_child(parent, tag, string("r0")); cxml::add_child(node, "InstanceID", string("r1"))->add_child_text("urn:uuid:" + instance_id); - cxml::add_child(node, "MCALabelDictionaryID", string("r1"))->add_child_text(mca_label_dictionary_id); + cxml::add_child(node, "MCALabelDictionaryID", string("r1"))->add_child_text("urn:smpte:ul:" + mca_label_dictionary_id); cxml::add_child(node, "MCALinkID", string("r1"))->add_child_text("urn:uuid:" + mca_link_id); cxml::add_child(node, "MCATagSymbol", string("r1"))->add_child_text(mca_tag_symbol); if (mca_tag_name) { @@ -82,3 +95,92 @@ MCASubDescriptor::as_xml(xmlpp::Element* parent) const } } + +pair<MCASubDescriptor, vector<MCASubDescriptor>> +dcp::create_mca_subdescriptors(vector<dcp::Channel> const& extra_active_channels, int total_channels, optional<string> language) +{ + /* We always make a descriptor for these channels if they are present in the asset; + * there's no way for the caller to tell us whether they are active or not. + */ + std::vector<dcp::Channel> dcp_channels = { + Channel::LEFT, + Channel::RIGHT, + Channel::CENTRE, + Channel::LFE, + Channel::LS, + Channel::RS + }; + + /* We add descriptors for some extra channels that the caller gave us (we made sure earlier + * that nothing "bad" is in this list). + */ + std::copy(extra_active_channels.begin(), extra_active_channels.end(), back_inserter(dcp_channels)); + + /* Remove duplicates */ + std::sort(dcp_channels.begin(), dcp_channels.end()); + dcp_channels.erase(std::unique(dcp_channels.begin(), dcp_channels.end()), dcp_channels.end()); + + /* Remove channels that aren't actually in this MXF at all */ + dcp_channels.erase( + std::remove_if(dcp_channels.begin(), dcp_channels.end(), [total_channels](dcp::Channel channel) { + return static_cast<int>(channel) >= total_channels; + }), + dcp_channels.end() + ); + + MCASoundField const field = + ( + find(extra_active_channels.begin(), extra_active_channels.end(), dcp::Channel::BSL) != extra_active_channels.end() || + find(extra_active_channels.begin(), extra_active_channels.end(), dcp::Channel::BSR) != extra_active_channels.end() + ) ? MCASoundField::SEVEN_POINT_ONE : MCASoundField::FIVE_POINT_ONE; + + auto group = MCASubDescriptor("SoundfieldGroupLabelSubDescriptor"); + byte_t const* id = nullptr; + group.mca_link_id = make_uuid(); + switch (field) { + case MCASoundField::SEVEN_POINT_ONE: + id = asdcp_smpte_dict->ul(ASDCP::MDD_DCAudioSoundfield_71); + group.mca_tag_symbol = "sg71"; + group.mca_tag_name = "7.1DS"; + break; + case MCASoundField::FIVE_POINT_ONE: + id = asdcp_smpte_dict->ul(ASDCP::MDD_DCAudioSoundfield_51); + group.mca_tag_symbol = "sg51"; + group.mca_tag_name = "5.1"; + break; + case MCASoundField::OTHER: + break; + } + + if (id) { + group.mca_label_dictionary_id = fmt::format( + "{:02x}{:02x}{:02x}{:02x}.{:02x}{:02x}{:02x}{:02x}.{:02x}{:02x}{:02x}{:02x}.{:02x}{:02x}{:02x}{:02x}", + id[0], id[1], id[2], id[3], + id[4], id[5], id[6], id[7], + id[8], id[9], id[10], id[11], + id[12], id[13], id[14], id[15] + ); + } + + vector<MCASubDescriptor> channels; + for (auto dcp_channel: dcp_channels) { + auto channel = MCASubDescriptor("AudioChannelLabelSubDescriptor"); + channel.soundfield_group_link_id = group.mca_link_id; + channel.mca_channel_id = fmt::to_string(static_cast<int>(dcp_channel) + 1); + channel.mca_tag_symbol = "ch" + channel_to_mca_id(dcp_channel, field); + channel.mca_tag_name = channel_to_mca_name(dcp_channel, field); + channel.rfc5646_spoken_language = language; + auto label = channel_to_mca_universal_label(dcp_channel, field, asdcp_smpte_dict).Value(); + channel.mca_label_dictionary_id = fmt::format( + "{:02x}{:02x}{:02x}{:02x}.{:02x}{:02x}{:02x}{:02x}.{:02x}{:02x}{:02x}{:02x}.{:02x}{:02x}{:02x}{:02x}", + label[0], label[1], label[2], label[3], + label[4], label[5], label[6], label[7], + label[8], label[9], label[10], label[11], + label[12], label[13], label[14], label[15] + ); + channels.push_back(channel); + } + + return { group, channels }; +} + |
