+
+ auto eml = node->optional_node_child ("ExtensionMetadataList");
+
+ auto extension_metadata = [eml](string scope, string name, string property) -> boost::optional<std::string> {
+ if (!eml) {
+ return {};
+ }
+
+ for (auto i: eml->node_children("ExtensionMetadata")) {
+ auto xml_scope = i->optional_string_attribute("scope");
+ auto xml_name = i->optional_string_child("Name");
+ if (xml_scope && *xml_scope == scope && xml_name && *xml_name == name) {
+ auto property_list = i->node_child("PropertyList");
+ for (auto j: property_list->node_children("Property")) {
+ auto property_name = j->optional_string_child("Name");
+ auto property_value = j->optional_string_child("Value");
+ if (property_name && property_value && *property_name == property) {
+ return property_value;
+ }
+ }
+ }
+ }
+
+ return {};
+ };
+
+ _sign_language_video_language = extension_metadata("http://isdcf.com/2017/10/SignLanguageVideo", "Sign Language Video", "Language Tag");
+ _dolby_edr_image_transfer_function = extension_metadata("http://www.dolby.com/schemas/2014/EDR-Metadata", "Dolby EDR", "image transfer function");
+}
+
+
+void
+CPL::write_mca_subdescriptors(xmlpp::Element* parent, shared_ptr<const SoundAsset> asset) const
+{
+ auto reader = asset->start_read ();
+ ASDCP::MXF::SoundfieldGroupLabelSubDescriptor* soundfield;
+ ASDCP::Result_t r = reader->reader()->OP1aHeader().GetMDObjectByType(
+ asdcp_smpte_dict->ul(ASDCP::MDD_SoundfieldGroupLabelSubDescriptor),
+ reinterpret_cast<ASDCP::MXF::InterchangeObject**>(&soundfield)
+ );
+ if (KM_SUCCESS(r)) {
+ auto mca_subs = parent->add_child("mca:MCASubDescriptors");
+ mca_subs->set_namespace_declaration (mca_sub_descriptors_ns, "mca");
+ mca_subs->set_namespace_declaration (smpte_395_ns, "r0");
+ mca_subs->set_namespace_declaration (smpte_335_ns, "r1");
+ auto sf = mca_subs->add_child("SoundfieldGroupLabelSubDescriptor", "r0");
+ char buffer[64];
+ soundfield->InstanceUID.EncodeString(buffer, sizeof(buffer));
+ sf->add_child("InstanceID", "r1")->add_child_text("urn:uuid:" + string(buffer));
+ soundfield->MCALabelDictionaryID.EncodeString(buffer, sizeof(buffer));
+ sf->add_child("MCALabelDictionaryID", "r1")->add_child_text("urn:smpte:ul:" + string(buffer));
+ soundfield->MCALinkID.EncodeString(buffer, sizeof(buffer));
+ sf->add_child("MCALinkID", "r1")->add_child_text("urn:uuid:" + string(buffer));
+ soundfield->MCATagSymbol.EncodeString(buffer, sizeof(buffer));
+ sf->add_child("MCATagSymbol", "r1")->add_child_text(buffer);
+ if (!soundfield->MCATagName.empty()) {
+ soundfield->MCATagName.get().EncodeString(buffer, sizeof(buffer));
+ sf->add_child("MCATagName", "r1")->add_child_text(buffer);
+ }
+ if (!soundfield->RFC5646SpokenLanguage.empty()) {
+ soundfield->RFC5646SpokenLanguage.get().EncodeString(buffer, sizeof(buffer));
+ sf->add_child("RFC5646SpokenLanguage", "r1")->add_child_text(buffer);
+ }
+
+ /* Find the MCA subdescriptors in the MXF so that we can also write them here */
+ list<ASDCP::MXF::InterchangeObject*> channels;
+ auto r = reader->reader()->OP1aHeader().GetMDObjectsByType(
+ asdcp_smpte_dict->ul(ASDCP::MDD_AudioChannelLabelSubDescriptor),
+ channels
+ );
+
+ for (auto i: channels) {
+ auto channel = reinterpret_cast<ASDCP::MXF::AudioChannelLabelSubDescriptor*>(i);
+ auto ch = mca_subs->add_child("AudioChannelLabelSubDescriptor", "r0");
+ channel->InstanceUID.EncodeString(buffer, sizeof(buffer));
+ ch->add_child("InstanceID", "r1")->add_child_text("urn:uuid:" + string(buffer));
+ channel->MCALabelDictionaryID.EncodeString(buffer, sizeof(buffer));
+ ch->add_child("MCALabelDictionaryID", "r1")->add_child_text("urn:smpte:ul:" + string(buffer));
+ channel->MCALinkID.EncodeString(buffer, sizeof(buffer));
+ ch->add_child("MCALinkID", "r1")->add_child_text("urn:uuid:" + string(buffer));
+ channel->MCATagSymbol.EncodeString(buffer, sizeof(buffer));
+ ch->add_child("MCATagSymbol", "r1")->add_child_text(buffer);
+ if (!channel->MCATagName.empty()) {
+ channel->MCATagName.get().EncodeString(buffer, sizeof(buffer));
+ ch->add_child("MCATagName", "r1")->add_child_text(buffer);
+ }
+ if (!channel->MCAChannelID.empty()) {
+ ch->add_child("MCAChannelID", "r1")->add_child_text(raw_convert<string>(channel->MCAChannelID.get()));
+ }
+ if (!channel->RFC5646SpokenLanguage.empty()) {
+ channel->RFC5646SpokenLanguage.get().EncodeString(buffer, sizeof(buffer));
+ ch->add_child("RFC5646SpokenLanguage", "r1")->add_child_text(buffer);
+ }
+ if (!channel->SoundfieldGroupLinkID.empty()) {
+ channel->SoundfieldGroupLinkID.get().EncodeString(buffer, sizeof(buffer));
+ ch->add_child("SoundfieldGroupLinkID", "r1")->add_child_text("urn:uuid:" + string(buffer));
+ }
+ }
+ }