void ASDCP::UMID::MakeUMID(int Type, const UUID& AssetID) { // Set the non-varying base of the UMID static const byte_t UMIDBase[10] = { 0x06, 0x0a, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }; memcpy(m_Value, UMIDBase, 10); m_Value[10] = Type; // Material Type m_Value[12] = 0x13; // length // preserved for compatibility with mfxlib if( Type > 4 ) m_Value[7] = 5; m_Value[11] = 0x20; // UUID/UL method, number gen undefined // Instance Number m_Value[13] = m_Value[14] = m_Value[15] = 0; memcpy(&m_Value[16], AssetID.Value(), AssetID.Size()); m_HasValue = true; }
Result_t ASDCP::TimedText::DCSubtitleParser::h__SubtitleParser::OpenRead() { if ( ! m_Root.ParseString(m_XMLDoc.c_str()) ) return RESULT_FORMAT; m_TDesc.EncodingName = "UTF-8"; // the XML parser demands UTF-8 m_TDesc.ResourceList.clear(); m_TDesc.ContainerDuration = 0; const XMLNamespace* ns = m_Root.Namespace(); if ( ns == 0 ) { DefaultLogSink(). Warn("Document has no namespace name, assuming %s\n", c_dcst_namespace_name); m_TDesc.NamespaceName = c_dcst_namespace_name; } else { m_TDesc.NamespaceName = ns->Name(); } UUID DocID; if ( ! get_UUID_from_child_element("Id", &m_Root, DocID) ) { DefaultLogSink(). Error("Id element missing from input document\n"); return RESULT_FORMAT; } memcpy(m_TDesc.AssetID, DocID.Value(), DocID.Size()); XMLElement* EditRate = m_Root.GetChildWithName("EditRate"); if ( EditRate == 0 ) { DefaultLogSink(). Error("EditRate element missing from input document\n"); return RESULT_FORMAT; } m_TDesc.EditRate = decode_rational(EditRate->GetBody().c_str()); if ( m_TDesc.EditRate != EditRate_23_98 && m_TDesc.EditRate != EditRate_24 && m_TDesc.EditRate != EditRate_25 && m_TDesc.EditRate != EditRate_30 && m_TDesc.EditRate != EditRate_48 && m_TDesc.EditRate != EditRate_50 && m_TDesc.EditRate != EditRate_60 ) { DefaultLogSink(). Error("Unexpected EditRate: %d/%d\n", m_TDesc.EditRate.Numerator, m_TDesc.EditRate.Denominator); return RESULT_FORMAT; } // list of fonts ElementList FontList; m_Root.GetChildrenWithName("LoadFont", FontList); for ( Elem_i i = FontList.begin(); i != FontList.end(); i++ ) { UUID AssetID; if ( ! get_UUID_from_element(*i, AssetID) ) { DefaultLogSink(). Error("LoadFont element does not contain a urn:uuid value as expected.\n"); return RESULT_FORMAT; } TimedTextResourceDescriptor TmpResource; memcpy(TmpResource.ResourceID, AssetID.Value(), UUIDlen); TmpResource.Type = MT_OPENTYPE; m_TDesc.ResourceList.push_back(TmpResource); m_ResourceTypes.insert(ResourceTypeMap_t::value_type(UUID(TmpResource.ResourceID), MT_OPENTYPE)); } // list of images ElementList ImageList; m_Root.GetChildrenWithName("Image", ImageList); std::set<Kumu::UUID> visited_items; for ( Elem_i i = ImageList.begin(); i != ImageList.end(); i++ ) { UUID AssetID; if ( ! get_UUID_from_element(*i, AssetID) ) { DefaultLogSink(). Error("Image element does not contain a urn:uuid value as expected.\n"); return RESULT_FORMAT; } if ( visited_items.find(AssetID) == visited_items.end() ) { TimedTextResourceDescriptor TmpResource; memcpy(TmpResource.ResourceID, AssetID.Value(), UUIDlen); TmpResource.Type = MT_PNG; m_TDesc.ResourceList.push_back(TmpResource); m_ResourceTypes.insert(ResourceTypeMap_t::value_type(UUID(TmpResource.ResourceID), MT_PNG)); visited_items.insert(AssetID); } } // Calculate the timeline duration. // This is a little ugly because the last element in the file is not necessarily // the last instance to be displayed, e.g., element n and element n-1 may have the // same start time but n-1 may have a greater duration making it the last to be seen. // We must scan the list to accumulate the latest TimeOut value. ElementList InstanceList; ElementList::const_iterator ei; ui32_t end_count = 0; m_Root.GetChildrenWithName("Subtitle", InstanceList); if ( InstanceList.empty() ) { DefaultLogSink(). Error("XML document contains no Subtitle elements.\n"); return RESULT_FORMAT; } // assumes edit rate is constrained above ui32_t TCFrameRate = ( m_TDesc.EditRate == EditRate_23_98 ) ? 24 : m_TDesc.EditRate.Numerator; S12MTimecode beginTC; beginTC.SetFPS(TCFrameRate); XMLElement* StartTime = m_Root.GetChildWithName("StartTime"); if ( StartTime != 0 ) beginTC.DecodeString(StartTime->GetBody()); for ( ei = InstanceList.begin(); ei != InstanceList.end(); ei++ ) { S12MTimecode tmpTC((*ei)->GetAttrWithName("TimeOut"), TCFrameRate); if ( end_count < tmpTC.GetFrames() ) end_count = tmpTC.GetFrames(); } if ( end_count <= beginTC.GetFrames() ) { DefaultLogSink(). Error("Timed Text file has zero-length timeline.\n"); return RESULT_FORMAT; } m_TDesc.ContainerDuration = end_count - beginTC.GetFrames(); return RESULT_OK; }