X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=src%2FTimedText_Parser.cpp;h=191a3535d5198d66e1f14b8931c1eee8cc74ea44;hb=5584493c50cfa0541398527741253a0db8cdbf18;hp=099e9077c01833f818ad2facc3d7109ffede854d;hpb=64a6962252cb59b4ea4f77973611bf9692993b51;p=asdcplib.git diff --git a/src/TimedText_Parser.cpp b/src/TimedText_Parser.cpp index 099e907..191a353 100644 --- a/src/TimedText_Parser.cpp +++ b/src/TimedText_Parser.cpp @@ -1,5 +1,5 @@ /* -Copyright (c) 2007-2008, John Hurst +Copyright (c) 2007-2009, John Hurst All rights reserved. Redistribution and use in source and binary forms, with or without @@ -78,8 +78,12 @@ public: if ( KM_SUCCESS(result) ) { - ui32_t read_count = 0; - result = Reader.Read(FrameBuf.Data(), FrameBuf.Capacity(), &read_count); + ui32_t read_count, read_size = Reader.Size(); + + result = FrameBuf.Capacity(read_size); + + if ( KM_SUCCESS(result) ) + result = Reader.Read(FrameBuf.Data(), read_size, &read_count); if ( KM_SUCCESS(result) ) FrameBuf.Size(read_count); @@ -97,6 +101,7 @@ class ASDCP::TimedText::DCSubtitleParser::h__SubtitleParser { XMLElement m_Root; ResourceTypeMap_t m_ResourceTypes; + Result_t OpenRead(); ASDCP_NO_COPY_CONSTRUCT(h__SubtitleParser); @@ -122,6 +127,7 @@ public: } Result_t OpenRead(const char* filename); + Result_t OpenRead(const std::string& xml_doc, const char* filename); Result_t ReadAncillaryResource(const byte_t* uuid, FrameBuffer& FrameBuf, const IResourceResolver& Resolver) const; }; @@ -166,13 +172,34 @@ ASDCP::TimedText::DCSubtitleParser::h__SubtitleParser::OpenRead(const char* file { Result_t result = ReadFileIntoString(filename, m_XMLDoc); - if ( KM_FAILURE(result) ) - return result; + if ( KM_SUCCESS(result) ) + result = OpenRead(); + + m_Filename = filename; + return result; +} + +// +Result_t +ASDCP::TimedText::DCSubtitleParser::h__SubtitleParser::OpenRead(const std::string& xml_doc, const char* filename) +{ + m_XMLDoc = xml_doc; + + if ( filename != 0 ) + m_Filename = filename; + else + m_Filename = ""; + return OpenRead(); +} + +// +Result_t +ASDCP::TimedText::DCSubtitleParser::h__SubtitleParser::OpenRead() +{ if ( ! m_Root.ParseString(m_XMLDoc.c_str()) ) return RESULT_FORMAT; - m_Filename = filename; m_TDesc.EncodingName = "UTF-8"; // the XML parser demands UTF-8 m_TDesc.ResourceList.clear(); m_TDesc.ContainerDuration = 0; @@ -184,7 +211,9 @@ ASDCP::TimedText::DCSubtitleParser::h__SubtitleParser::OpenRead(const char* file m_TDesc.NamespaceName = c_dcst_namespace_name; } else - m_TDesc.NamespaceName = ns->Name(); + { + m_TDesc.NamespaceName = ns->Name(); + } UUID DocID; if ( ! get_UUID_from_child_element("Id", &m_Root, DocID) ) @@ -204,9 +233,16 @@ ASDCP::TimedText::DCSubtitleParser::h__SubtitleParser::OpenRead(const char* file m_TDesc.EditRate = decode_rational(EditRate->GetBody().c_str()); - if ( m_TDesc.EditRate != EditRate_24 && m_TDesc.EditRate != EditRate_48 ) + 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("EditRate must be 24/1 or 48/1\n"); + DefaultLogSink(). Error("Unexpected EditRate: %d/%d\n", + m_TDesc.EditRate.Numerator, m_TDesc.EditRate.Denominator); return RESULT_FORMAT; } @@ -263,21 +299,33 @@ ASDCP::TimedText::DCSubtitleParser::h__SubtitleParser::OpenRead(const char* file if ( InstanceList.empty() ) { - DefaultLogSink(). Error("XML document contains no Subtitle elements!\n"); + DefaultLogSink(). Error("XML document contains no Subtitle elements.\n"); return RESULT_FORMAT; } - // assumes 24/1 or 48/1 as constrained above - S12MTimecode beginTC(InstanceList.front()->GetAttrWithName("TimeIn"), m_TDesc.EditRate.Numerator); + // 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"), m_TDesc.EditRate.Numerator); + S12MTimecode tmpTC((*ei)->GetAttrWithName("TimeOut"), TCFrameRate); if ( end_count < tmpTC.GetFrames() ) end_count = tmpTC.GetFrames(); } - assert( end_count > beginTC.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; @@ -343,9 +391,23 @@ ASDCP::TimedText::DCSubtitleParser::OpenRead(const char* filename) const return result; } +// Parses an XML document to provide a complete set of stream metadata for the MXFWriter below. +Result_t +ASDCP::TimedText::DCSubtitleParser::OpenRead(const std::string& xml_doc, const char* filename) const +{ + const_cast(this)->m_Parser = new h__SubtitleParser; + + Result_t result = m_Parser->OpenRead(xml_doc, filename); + + if ( ASDCP_FAILURE(result) ) + const_cast(this)->m_Parser = 0; + + return result; +} + // ASDCP::Result_t -ASDCP::TimedText::DCSubtitleParser::FillDescriptor(TimedTextDescriptor& TDesc) const +ASDCP::TimedText::DCSubtitleParser::FillTimedTextDescriptor(TimedTextDescriptor& TDesc) const { if ( m_Parser.empty() ) return RESULT_INIT;