From 4564a68b8a586b49715f39fb84271db61fc109b7 Mon Sep 17 00:00:00 2001 From: jhurst Date: Sat, 22 Dec 2007 19:32:35 +0000 Subject: [PATCH] logging re-write --- README | 21 ++-- src/AS_DCP_JP2K.cpp | 21 +++- src/AS_DCP_MXF.cpp | 2 +- src/AS_DCP_TimedText.cpp | 82 ++++++++-------- src/KM_error.h | 1 + src/KM_log.cpp | 205 ++++++++++++++++++++++++++------------- src/KM_log.h | 186 ++++++++++++++++++++++++++++++----- src/KM_memio.h | 6 +- src/KM_util.cpp | 70 ++++++++++--- src/KM_util.h | 106 +++++++++++--------- src/MDD.cpp | 67 ++++++------- src/MDD.h | 21 ++-- src/MXF.h | 22 +++-- src/MXFTypes.h | 31 +++++- src/Metadata.cpp | 77 ++++++++------- src/Metadata.h | 31 +++--- src/S12MTimecode.h | 1 + src/TimedText_Parser.cpp | 2 +- src/asdcp-test.cpp | 29 +++++- 19 files changed, 670 insertions(+), 311 deletions(-) diff --git a/README b/README index 5d863bc..ab795c3 100755 --- a/README +++ b/README @@ -116,17 +116,26 @@ utilities all respond to -h. Change History -2007.10.29 - Bug fixes v.1.2.17 +2007.12.13 - Bug fixes v.1.2.17 o Changed Result_t implementation to use int instead of long, which was causing trouble on some 64 bit platforms. - o Fixed EKLV HMAC. Broke backward compatibility with older Interop - files. To validate these files use asdcplib-1.1.14. This should - not cause too much trouble since files with broken and non-broken - HMAC have been in the wild for years without trouble. + o Fixed EKLV HMAC. NOTE: Breaks backward compatibility with older + Interop files. To validate these files, use asdcplib-1.1.14. This + should not cause too much trouble since files with broken and + non-broken HMAC have been in the wild for years without issue. o Fixed HMAC sequence numbering in encrypted stereoscopic files. o Finished stereoscopic test targets in the makefile. o Fixed the win32 build, now expects VS2005 compiler by default, - use WITH_VC6=1 top get VS6 flags. + use WITH_VC6=1 top get VC6 flags. + o Stereoscopic and Timed Text modes now have SMPTE UL values. + NOTE: SMPTE 429-5 and 429-10 are not yet published. It is possible + that these UL values may change before publication. Please use + caution when using these features for production work. + o Changed a bunch of symbol names in the 429-5 implementation to + better match the spec. + o Added -U option to asdcp-test to dump the UL library to stdout. + o Fixed erroneous placement of the PictureEssenceCoding UL in JP2K + files (Interop and SMPTE modes). 2007.10.22 - Timed Text, Stereoscopic Picture and Bug fixes v.1.2.16 diff --git a/src/AS_DCP_JP2K.cpp b/src/AS_DCP_JP2K.cpp index a1d9514..8f77173 100755 --- a/src/AS_DCP_JP2K.cpp +++ b/src/AS_DCP_JP2K.cpp @@ -570,6 +570,9 @@ public: Result_t JP2K_PDesc_to_MD(JP2K::PictureDescriptor& PDesc); }; +const int VideoLineMapSize = 16; // See SMPTE 377M D.2.1 +const int PixelLayoutSize = 8*2; // See SMPTE 377M D.2.3 +static const byte_t s_PixelLayoutXYZ[PixelLayoutSize] = { 0xd8, 0x0c, 0xd9, 0x0c, 0xda, 0x0c, 0x00 }; // ASDCP::Result_t @@ -579,21 +582,31 @@ lh__Writer::JP2K_PDesc_to_MD(JP2K::PictureDescriptor& PDesc) assert(m_EssenceSubDescriptor); MXF::RGBAEssenceDescriptor* PDescObj = (MXF::RGBAEssenceDescriptor*)m_EssenceDescriptor; - PDescObj->SampleRate = PDesc.EditRate; PDescObj->ContainerDuration = PDesc.ContainerDuration; + PDescObj->SampleRate = PDesc.EditRate; + PDescObj->FrameLayout = 0; PDescObj->StoredWidth = PDesc.StoredWidth; PDescObj->StoredHeight = PDesc.StoredHeight; PDescObj->AspectRatio = PDesc.AspectRatio; - PDescObj->FrameLayout = 0; + + // if ( m_Info.LabelSetType == LS_MXF_SMPTE ) + // { + // PictureEssenceCoding UL = + // Video Line Map ui32_t[VideoLineMapSize] = { 2, 4, 0, 0 } + // CaptureGamma UL = + // ComponentMaxRef ui32_t = 4095 + // ComponentMinRef ui32_t = 0 + // PixelLayout byte_t[PixelLayoutSize] = s_PixelLayoutXYZ + // } if ( PDesc.StoredWidth < 2049 ) { - PDescObj->Codec.Set(Dict::ul(MDD_JP2KEssenceCompression_2K)); + PDescObj->PictureEssenceCoding.Set(Dict::ul(MDD_JP2KEssenceCompression_2K)); m_EssenceSubDescriptor->Rsize = 3; } else { - PDescObj->Codec.Set(Dict::ul(MDD_JP2KEssenceCompression_4K)); + PDescObj->PictureEssenceCoding.Set(Dict::ul(MDD_JP2KEssenceCompression_4K)); m_EssenceSubDescriptor->Rsize = 4; } diff --git a/src/AS_DCP_MXF.cpp b/src/AS_DCP_MXF.cpp index 2392057..192965d 100755 --- a/src/AS_DCP_MXF.cpp +++ b/src/AS_DCP_MXF.cpp @@ -158,7 +158,7 @@ ASDCP::EssenceType(const char* filename, EssenceType_t& type) type = ESS_PCM_24b_48k; else if ( ASDCP_SUCCESS(TestHeader.GetMDObjectByType(OBJ_TYPE_ARGS(MPEG2VideoDescriptor))) ) type = ESS_MPEG2_VES; - else if ( ASDCP_SUCCESS(TestHeader.GetMDObjectByType(OBJ_TYPE_ARGS(DCTimedTextDescriptor))) ) + else if ( ASDCP_SUCCESS(TestHeader.GetMDObjectByType(OBJ_TYPE_ARGS(TimedTextDescriptor))) ) type = ESS_TIMED_TEXT; } diff --git a/src/AS_DCP_TimedText.cpp b/src/AS_DCP_TimedText.cpp index 7f89b1f..47a0279 100644 --- a/src/AS_DCP_TimedText.cpp +++ b/src/AS_DCP_TimedText.cpp @@ -33,7 +33,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "AS_DCP_internal.h" #include "KM_xml.h" -static std::string TIMED_TEXT_PACKAGE_LABEL = "File Package: SMPTE 429-5 frame wrapping of D-Cinema Timed Text data"; +static std::string TIMED_TEXT_PACKAGE_LABEL = "File Package: SMPTE 429-5 clip wrapping of D-Cinema Timed Text data"; static std::string TIMED_TEXT_DEF_LABEL = "Timed Text Track"; @@ -46,7 +46,7 @@ MIME2str(TimedText::MIMEType_t m) return "image/png"; else if ( m == TimedText::MT_OPENTYPE ) - return "application/x-opentype"; + return "application/x-font-opentype"; return "application/octet-stream"; } @@ -64,8 +64,8 @@ ASDCP::TimedText::DescriptorDump(ASDCP::TimedText::TimedTextDescriptor const& TD fprintf(stream, " EditRate: %u/%u\n", TDesc.EditRate.Numerator, TDesc.EditRate.Denominator); fprintf(stream, "ContainerDuration: %u\n", TDesc.ContainerDuration); fprintf(stream, " AssetID: %s\n", TmpID.EncodeHex(buf, 64)); - fprintf(stream, " NamespaceName: %s\n", TDesc.NamespaceName.c_str()); - fprintf(stream, " ResourceCount: %lu\n", TDesc.ResourceList.size()); + fprintf(stream, " NamespaceName: %s\n", TDesc.NamespaceName.c_str()); + fprintf(stream, " ResourceCount: %lu\n", TDesc.ResourceList.size()); TimedText::ResourceList_t::const_iterator ri; for ( ri = TDesc.ResourceList.begin() ; ri != TDesc.ResourceList.end(); ri++ ) @@ -98,8 +98,8 @@ typedef std::map ResourceMap_t; class ASDCP::TimedText::MXFReader::h__Reader : public ASDCP::h__Reader { - DCTimedTextDescriptor* m_EssenceDescriptor; - ResourceMap_t m_ResourceMap; + MXF::TimedTextDescriptor* m_EssenceDescriptor; + ResourceMap_t m_ResourceMap; ASDCP_NO_COPY_CONSTRUCT(h__Reader); @@ -122,40 +122,40 @@ ASDCP::TimedText::MXFReader::h__Reader::MD_to_TimedText_TDesc(TimedText::TimedTe { assert(m_EssenceDescriptor); memset(&m_TDesc.AssetID, 0, UUIDlen); - MXF::DCTimedTextDescriptor* TDescObj = (MXF::DCTimedTextDescriptor*)m_EssenceDescriptor; + MXF::TimedTextDescriptor* TDescObj = (MXF::TimedTextDescriptor*)m_EssenceDescriptor; TDesc.EditRate = TDescObj->SampleRate; TDesc.ContainerDuration = TDescObj->ContainerDuration; memcpy(TDesc.AssetID, TDescObj->ResourceID.Value(), UUIDlen); - TDesc.NamespaceName = TDescObj->RootNamespaceName; - TDesc.EncodingName = TDescObj->UTFEncoding; + TDesc.NamespaceName = TDescObj->NamespaceURI; + TDesc.EncodingName = TDescObj->UCSEncoding; Batch::const_iterator sdi = TDescObj->SubDescriptors.begin(); - DCTimedTextResourceDescriptor* DescObject = 0; + TimedTextResourceSubDescriptor* DescObject = 0; Result_t result = RESULT_OK; for ( ; sdi != TDescObj->SubDescriptors.end() && KM_SUCCESS(result); sdi++ ) { InterchangeObject* tmp_iobj = 0; result = m_HeaderPart.GetMDObjectByID(*sdi, &tmp_iobj); - DescObject = static_cast(tmp_iobj); + DescObject = static_cast(tmp_iobj); if ( KM_SUCCESS(result) ) { TimedTextResourceDescriptor TmpResource; - memcpy(TmpResource.ResourceID, DescObject->ResourceID.Value(), UUIDlen); + memcpy(TmpResource.ResourceID, DescObject->AncillaryResourceID.Value(), UUIDlen); - if ( DescObject->ResourceMIMEType.find("font/") != std::string::npos ) + if ( DescObject->MIMEMediaType.find("font/") != std::string::npos ) TmpResource.Type = MT_OPENTYPE; - else if ( DescObject->ResourceMIMEType.find("image/png") != std::string::npos ) + else if ( DescObject->MIMEMediaType.find("image/png") != std::string::npos ) TmpResource.Type = MT_PNG; else TmpResource.Type = MT_BIN; TDesc.ResourceList.push_back(TmpResource); - m_ResourceMap.insert(ResourceMap_t::value_type(DescObject->ResourceID, *sdi)); + m_ResourceMap.insert(ResourceMap_t::value_type(DescObject->AncillaryResourceID, *sdi)); } else { @@ -178,8 +178,8 @@ ASDCP::TimedText::MXFReader::h__Reader::OpenRead(char const* filename) if ( m_EssenceDescriptor == 0 ) { InterchangeObject* tmp_iobj = 0; - result = m_HeaderPart.GetMDObjectByType(OBJ_TYPE_ARGS(DCTimedTextDescriptor), &tmp_iobj); - m_EssenceDescriptor = static_cast(tmp_iobj); + result = m_HeaderPart.GetMDObjectByType(OBJ_TYPE_ARGS(TimedTextDescriptor), &tmp_iobj); + m_EssenceDescriptor = static_cast(tmp_iobj); } if( ASDCP_SUCCESS(result) ) @@ -203,7 +203,7 @@ ASDCP::TimedText::MXFReader::h__Reader::ReadTimedTextResource(FrameBuffer& Frame if ( ! m_File.IsOpen() ) return RESULT_INIT; - Result_t result = ReadEKLVFrame(0, FrameBuf, Dict::ul(MDD_DCTimedTextEssence), Ctx, HMAC); + Result_t result = ReadEKLVFrame(0, FrameBuf, Dict::ul(MDD_TimedTextEssence), Ctx, HMAC); if( ASDCP_SUCCESS(result) ) { @@ -230,11 +230,11 @@ ASDCP::TimedText::MXFReader::h__Reader::ReadAncillaryResource(const byte_t* uuid return RESULT_RANGE; } - DCTimedTextResourceDescriptor* DescObject = 0; + TimedTextResourceSubDescriptor* DescObject = 0; // get the subdescriptor InterchangeObject* tmp_iobj = 0; Result_t result = m_HeaderPart.GetMDObjectByID((*ri).second, &tmp_iobj); - DescObject = static_cast(tmp_iobj); + DescObject = static_cast(tmp_iobj); if ( KM_SUCCESS(result) ) { @@ -247,7 +247,7 @@ ASDCP::TimedText::MXFReader::h__Reader::ReadAncillaryResource(const byte_t* uuid // value needed to complete the HMAC. for ( pi = m_HeaderPart.m_RIP.PairArray.begin(); pi != m_HeaderPart.m_RIP.PairArray.end(); pi++, sequence++ ) { - if ( (*pi).BodySID == DescObject->ResourceSID ) + if ( (*pi).BodySID == DescObject->EssenceStreamID ) { TmpPair = *pi; break; @@ -256,14 +256,14 @@ ASDCP::TimedText::MXFReader::h__Reader::ReadAncillaryResource(const byte_t* uuid if ( TmpPair.ByteOffset == 0 ) { - DefaultLogSink().Error("Body SID not found in RIP set: %d\n", DescObject->ResourceSID); + DefaultLogSink().Error("Body SID not found in RIP set: %d\n", DescObject->EssenceStreamID); return RESULT_FORMAT; } if ( KM_SUCCESS(result) ) { FrameBuf.AssetID(uuid); - FrameBuf.MIMEType(DescObject->ResourceMIMEType); + FrameBuf.MIMEType(DescObject->MIMEMediaType); // seek tp the start of the partition if ( (Kumu::fpos_t)TmpPair.ByteOffset != m_LastPosition ) @@ -279,7 +279,7 @@ ASDCP::TimedText::MXFReader::h__Reader::ReadAncillaryResource(const byte_t* uuid if( ASDCP_SUCCESS(result) ) { // check the SID - if ( DescObject->ResourceSID != GSPart.BodySID ) + if ( DescObject->EssenceStreamID != GSPart.BodySID ) { char buf[64]; DefaultLogSink().Error("Generic stream partition body differs: %s\n", RID.EncodeHex(buf, 64)); @@ -288,7 +288,7 @@ ASDCP::TimedText::MXFReader::h__Reader::ReadAncillaryResource(const byte_t* uuid // read the essence packet if( ASDCP_SUCCESS(result) ) - result = ReadEKLVPacket(0, 1, FrameBuf, Dict::ul(MDD_DCTimedTextDescriptor), Ctx, HMAC); + result = ReadEKLVPacket(0, 1, FrameBuf, Dict::ul(MDD_TimedTextDescriptor), Ctx, HMAC); } } } @@ -408,11 +408,11 @@ class ASDCP::TimedText::MXFWriter::h__Writer : public ASDCP::h__Writer public: TimedTextDescriptor m_TDesc; byte_t m_EssenceUL[SMPTE_UL_LENGTH]; - ui32_t m_ResourceSID; + ui32_t m_EssenceStreamID; ASDCP_NO_COPY_CONSTRUCT(h__Writer); - h__Writer() : m_ResourceSID(10) { + h__Writer() : m_EssenceStreamID(10) { memset(m_EssenceUL, 0, SMPTE_UL_LENGTH); } @@ -431,13 +431,13 @@ ASDCP::Result_t ASDCP::TimedText::MXFWriter::h__Writer::TimedText_TDesc_to_MD(TimedText::TimedTextDescriptor& TDesc) { assert(m_EssenceDescriptor); - MXF::DCTimedTextDescriptor* TDescObj = (MXF::DCTimedTextDescriptor*)m_EssenceDescriptor; + MXF::TimedTextDescriptor* TDescObj = (MXF::TimedTextDescriptor*)m_EssenceDescriptor; TDescObj->SampleRate = TDesc.EditRate; TDescObj->ContainerDuration = TDesc.ContainerDuration; TDescObj->ResourceID.Set(TDesc.AssetID); - TDescObj->RootNamespaceName = TDesc.NamespaceName; - TDescObj->UTFEncoding = TDesc.EncodingName; + TDescObj->NamespaceURI = TDesc.NamespaceName; + TDescObj->UCSEncoding = TDesc.EncodingName; return RESULT_OK; } @@ -454,7 +454,7 @@ ASDCP::TimedText::MXFWriter::h__Writer::OpenWrite(char const* filename, ui32_t H if ( ASDCP_SUCCESS(result) ) { m_HeaderSize = HeaderSize; - m_EssenceDescriptor = new DCTimedTextDescriptor(); + m_EssenceDescriptor = new MXF::TimedTextDescriptor(); result = m_State.Goto_INIT(); } @@ -474,16 +474,16 @@ ASDCP::TimedText::MXFWriter::h__Writer::SetSourceStream(ASDCP::TimedText::TimedT for ( ri = m_TDesc.ResourceList.begin() ; ri != m_TDesc.ResourceList.end() && ASDCP_SUCCESS(result); ri++ ) { - DCTimedTextResourceDescriptor* resourceSubdescriptor = new DCTimedTextResourceDescriptor; + TimedTextResourceSubDescriptor* resourceSubdescriptor = new TimedTextResourceSubDescriptor; GenRandomValue(resourceSubdescriptor->InstanceUID); - resourceSubdescriptor->ResourceID.Set((*ri).ResourceID); - resourceSubdescriptor->ResourceMIMEType = MIME2str((*ri).Type); - resourceSubdescriptor->ResourceSID = m_ResourceSID++; + resourceSubdescriptor->AncillaryResourceID.Set((*ri).ResourceID); + resourceSubdescriptor->MIMEMediaType = MIME2str((*ri).Type); + resourceSubdescriptor->EssenceStreamID = m_EssenceStreamID++; m_EssenceSubDescriptorList.push_back((FileDescriptor*)resourceSubdescriptor); m_EssenceDescriptor->SubDescriptors.push_back(resourceSubdescriptor->InstanceUID); } - m_ResourceSID = 10; + m_EssenceStreamID = 10; if ( ASDCP_SUCCESS(result) ) { @@ -491,7 +491,7 @@ ASDCP::TimedText::MXFWriter::h__Writer::SetSourceStream(ASDCP::TimedText::TimedT AddDMSegment(m_TDesc.EditRate, 24, TIMED_TEXT_DEF_LABEL, UL(Dict::ul(MDD_PictureDataDef)), TIMED_TEXT_PACKAGE_LABEL); - AddEssenceDescriptor(UL(Dict::ul(MDD_DCTimedTextWrapping))); + AddEssenceDescriptor(UL(Dict::ul(MDD_TimedTextWrapping))); result = m_HeaderPart.WriteToFile(m_File, m_HeaderSize); @@ -501,7 +501,7 @@ ASDCP::TimedText::MXFWriter::h__Writer::SetSourceStream(ASDCP::TimedText::TimedT if ( ASDCP_SUCCESS(result) ) { - memcpy(m_EssenceUL, Dict::ul(MDD_DCTimedTextEssence), SMPTE_UL_LENGTH); + memcpy(m_EssenceUL, Dict::ul(MDD_TimedTextEssence), SMPTE_UL_LENGTH); m_EssenceUL[SMPTE_UL_LENGTH-1] = 1; // first (and only) essence container result = m_State.Goto_READY(); } @@ -558,11 +558,11 @@ ASDCP::TimedText::MXFWriter::h__Writer::WriteAncillaryResource(const ASDCP::Time GSPart.ThisPartition = here; GSPart.PreviousPartition = m_HeaderPart.m_RIP.PairArray.back().ByteOffset; - GSPart.BodySID = m_ResourceSID; + GSPart.BodySID = m_EssenceStreamID; GSPart.OperationalPattern = m_HeaderPart.OperationalPattern; - m_HeaderPart.m_RIP.PairArray.push_back(RIP::Pair(m_ResourceSID++, here)); - GSPart.EssenceContainers.push_back(UL(Dict::ul(MDD_DCTimedTextEssence))); + m_HeaderPart.m_RIP.PairArray.push_back(RIP::Pair(m_EssenceStreamID++, here)); + GSPart.EssenceContainers.push_back(UL(Dict::ul(MDD_TimedTextEssence))); UL TmpUL(Dict::ul(MDD_GenericStreamPartition)); Result_t result = GSPart.WriteToFile(m_File, TmpUL); diff --git a/src/KM_error.h b/src/KM_error.h index 31d4f3e..8ea7555 100755 --- a/src/KM_error.h +++ b/src/KM_error.h @@ -49,6 +49,7 @@ namespace Kumu public: static const Result_t& Find(int); + static Result_t Delete(int); Result_t(int v, const char* l); ~Result_t(); diff --git a/src/KM_log.cpp b/src/KM_log.cpp index a76df09..0c4a3bf 100755 --- a/src/KM_log.cpp +++ b/src/KM_log.cpp @@ -1,5 +1,5 @@ /* -Copyright (c) 2004-2006, John Hurst +Copyright (c) 2004-2007, John Hurst All rights reserved. Redistribution and use in source and binary forms, with or without @@ -41,27 +41,21 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #endif +//------------------------------------------------------------------------------------------ +// void -Kumu::StdioLogSink::vLogf(ILogSink::LogType_t type, const char* fmt, va_list* list) +Kumu::ILogSink::vLogf(LogType_t type, const char* fmt, va_list* list) { - AutoMutex L(m_Lock); + char buf[MaxLogLength]; + vsnprintf(buf, MaxLogLength, fmt, *list); - switch ( type ) - { - case LOG_CRIT: fprintf(m_stream, "[%d CRT]: ", getpid()); break; - case LOG_ALERT: fprintf(m_stream, "[%d ALR]: ", getpid()); break; - case LOG_NOTICE: fprintf(m_stream, "[%d NTC]: ", getpid()); break; - case LOG_ERROR: fprintf(m_stream, "[%d ERR]: ", getpid()); break; - case LOG_WARN: fprintf(m_stream, "[%d WRN]: ", getpid()); break; - case LOG_INFO: fprintf(m_stream, "[%d INF]: ", getpid()); break; - case LOG_DEBUG: fprintf(m_stream, "[%d DBG]: ", getpid()); break; - default: fprintf(m_stream, "[%d DFL]: ", getpid()); - } - - vfprintf(m_stream, fmt, *list); + WriteEntry(LogEntry(getpid(), type, buf)); } +//------------------------------------------------------------------------------------------ +// + static Kumu::ILogSink* s_DefaultLogSink; static Kumu::StdioLogSink s_StderrLogSink; @@ -82,74 +76,155 @@ Kumu::DefaultLogSink() return *s_DefaultLogSink; } +//------------------------------------------------------------------------------------------ +// + +void +Kumu::StdioLogSink::WriteEntry(const LogEntry& Entry) +{ + AutoMutex L(m_Lock); + std::string buf; + if ( Entry.CreateStringWithFilter(m_filter, buf) ) + fputs(buf.c_str(), m_stream); +} + //--------------------------------------------------------------------------------- + #ifdef KM_WIN32 +// +void +Kumu::WinDbgLogSink::WriteEntry(const LogEntry& Entry) +{ + AutoMutex L(m_Lock); + std::string buf; + if ( Entry.CreateStringWithFilter(m_filter, buf) ) + ::OutputDebugString(buf.c_str()); +} +#endif + +//------------------------------------------------------------------------------------------ +// +#ifndef KM_WIN32 // void -Kumu::WinDbgLogSink::vLogf(ILogSink::LogType_t type, const char* fmt, va_list* list) +Kumu::StreamLogSink::WriteEntry(const LogEntry& Entry) { AutoMutex L(m_Lock); - char msg_buf[MaxLogLength]; + std::string buf; + if ( Entry.CreateStringWithFilter(m_filter, buf) ) + write(m_fd, buf.c_str(), buf.size()); +} +#endif - DWORD pid = GetCurrentProcessId(); +//------------------------------------------------------------------------------------------ - switch ( type ) +bool +Kumu::LogEntry::CreateStringWithFilter(i32_t filter, std::string& out_buf) const +{ + const char* p = 0; + + switch ( Type ) { - case LOG_CRIT: snprintf(msg_buf, MaxLogLength, "[%d CRT]: ", pid); break; - case LOG_ALERT: snprintf(msg_buf, MaxLogLength, "[%d ALR]: ", pid); break; - case LOG_NOTICE: snprintf(msg_buf, MaxLogLength, "[%d NTC]: ", pid); break; - case LOG_ERROR: snprintf(msg_buf, MaxLogLength, "[%d ERR]: ", pid); break; - case LOG_WARN: snprintf(msg_buf, MaxLogLength, "[%d WRN]: ", pid); break; - case LOG_INFO: snprintf(msg_buf, MaxLogLength, "[%d INF]: ", pid); break; - case LOG_DEBUG: snprintf(msg_buf, MaxLogLength, "[%d DBG]: ", pid); break; - default: snprintf(msg_buf, MaxLogLength, "[%d DFL]: ", pid); + case LOG_CRIT: + if ( (filter & LOG_ALLOW_CRIT) != 0 ) + p = " CRT"; + break; + + case LOG_ALERT: + if ( (filter & LOG_ALLOW_ALERT) != 0 ) + p = " ALR"; + break; + + case LOG_NOTICE: + if ( (filter & LOG_ALLOW_NOTICE) != 0 ) + p = " NTC"; + break; + + case LOG_ERROR: + if ( (filter & LOG_ALLOW_ERROR) != 0 ) + p = " ERR"; + break; + + case LOG_WARN: + if ( (filter & LOG_ALLOW_WARN) != 0 ) + p = " WRN"; + break; + + case LOG_INFO: + if ( (filter & LOG_ALLOW_INFO) != 0 ) + p = " INF"; + break; + + case LOG_DEBUG: + if ( (filter & LOG_ALLOW_DEBUG) != 0 ) + p = " DBG"; + break; + + default: + if ( (filter & LOG_ALLOW_DEFAULT) != 0 ) + p = " DFL"; + break; } - - ui32_t len = strlen(msg_buf); - vsnprintf(msg_buf + len, MaxLogLength - len, fmt, *list); - msg_buf[MaxLogLength-1] = 0; - ::OutputDebugString(msg_buf); -} -#else + if ( p == 0 ) + return false; -void -Kumu::StreamLogSink::vLogf(ILogSink::LogType_t type, const char* fmt, va_list* list) -{ - AutoMutex L(m_Lock); - char msg_buf[MaxLogLength]; - char ts_buf[MaxLogLength]; - Timestamp Now; + char buf[64]; + out_buf = "["; - switch ( type ) + if ( (filter & LOG_ALLOW_TIMESTAMP) != 0 ) { - case LOG_CRIT: snprintf(msg_buf, MaxLogLength, "[%s %d CRT]: ", - Now.EncodeString(ts_buf, MaxLogLength), getpid()); break; - case LOG_ALERT: snprintf(msg_buf, MaxLogLength, "[%s %d ALR]: ", - Now.EncodeString(ts_buf, MaxLogLength), getpid()); break; - case LOG_NOTICE: snprintf(msg_buf, MaxLogLength, "[%s %d NTC]: ", - Now.EncodeString(ts_buf, MaxLogLength), getpid()); break; - case LOG_ERROR: snprintf(msg_buf, MaxLogLength, "[%s %d ERR]: ", - Now.EncodeString(ts_buf, MaxLogLength), getpid()); break; - case LOG_WARN: snprintf(msg_buf, MaxLogLength, "[%s %d WRN]: ", - Now.EncodeString(ts_buf, MaxLogLength), getpid()); break; - case LOG_INFO: snprintf(msg_buf, MaxLogLength, "[%s %d INF]: ", - Now.EncodeString(ts_buf, MaxLogLength), getpid()); break; - case LOG_DEBUG: snprintf(msg_buf, MaxLogLength, "[%s %d DBG]: ", - Now.EncodeString(ts_buf, MaxLogLength), getpid()); break; - default: snprintf(msg_buf, MaxLogLength, "[%s %d DFL]: ", - Now.EncodeString(ts_buf, MaxLogLength), getpid()); + Timestamp Now; + out_buf += Now.EncodeString(buf, 64); + + if ( (filter & LOG_ALLOW_PID) != 0 ) + out_buf += " "; + } + + if ( (filter & LOG_ALLOW_PID) != 0 ) + { + snprintf(buf, 64, "%d", PID); + out_buf += buf; } - - ui32_t len = strlen(msg_buf); - vsnprintf(msg_buf + len, MaxLogLength - len, fmt, *list); - msg_buf[MaxLogLength-1] = 0; - write(m_fd, msg_buf, strlen(msg_buf)); + + out_buf += "] " + Msg; + return true; } -#endif +// +ui32_t +Kumu::LogEntry::ArchiveLength() const +{ + return sizeof(ui32_t) + + EventTime.ArchiveLength() + + sizeof(ui32_t) + + sizeof(ui32_t) + Msg.size(); +} + +// +bool +Kumu::LogEntry::Archive(Kumu::MemIOWriter* Writer) const +{ + if ( ! Writer->WriteUi32BE(PID) ) return false; + if ( ! EventTime.Archive(Writer) ) return false; + if ( ! Writer->WriteUi32BE(Type) ) return false; + if ( ! ArchiveString(*Writer, Msg) ) return false; + return true; +} + +// +bool +Kumu::LogEntry::Unarchive(Kumu::MemIOReader* Reader) +{ + if ( ! Reader->ReadUi32BE(&PID) ) return false; + if ( ! EventTime.Unarchive(Reader) ) return false; + if ( ! Reader->ReadUi32BE((ui32_t*)&Type) ) return false; + if ( ! UnarchiveString(*Reader, Msg) ) return false; + return true; +} + // // end // diff --git a/src/KM_log.h b/src/KM_log.h index 9838f4c..0042119 100755 --- a/src/KM_log.h +++ b/src/KM_log.h @@ -1,5 +1,5 @@ /* -Copyright (c) 2004-2006, John Hurst +Copyright (c) 2004-2007, John Hurst All rights reserved. Redistribution and use in source and binary forms, with or without @@ -35,12 +35,15 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include +#include #include #include -#define LOG_MSG_IMPL(t) va_list args; va_start(args, fmt); vLogf((t), fmt, &args); va_end(args) - - +#define LOG_MSG_IMPL(t) \ + va_list args; \ + va_start(args, fmt); \ + vLogf((t), fmt, &args); \ + va_end(args) // Returns RESULT_PTR if the given argument is NULL. # define KM_TEST_NULL_L(p) \ @@ -69,30 +72,101 @@ namespace Kumu //--------------------------------------------------------------------------------- // message logging - // Error and debug messages will be delivered to an object having this interface. - // The default implementation sends only LOG_ERROR and LOG_WARN messages to stderr. - // To receive LOG_INFO or LOG_DEBUG messages, or to send messages somewhere other - // than stderr, implement this interface and register an instance of your new class - // by calling SetDefaultLogSink(). + // Log messages are recorded by objects which implement the interface given + // in the class ILogSink below. The library maintains a pointer to a default + // log sink which is used by the library to report messages. + // + + // types of log messages + enum LogType_t { + LOG_DEBUG, // detailed developer info + LOG_INFO, // developer info + LOG_WARN, // library non-fatal or near-miss error + LOG_ERROR, // library fatal error + LOG_NOTICE, // application user info + LOG_ALERT, // application non-fatal or near-miss error + LOG_CRIT, // application fatal error + }; + + + // OR these values together to come up with sink filter flags. + // The default mask is 0x0000ffff (no time stamp, no pid, all messages). + const i32_t LOG_ALLOW_TIMESTAMP = 0x01000000; + const i32_t LOG_ALLOW_PID = 0x02000000; + + const i32_t LOG_ALLOW_DEBUG = 0x00000001; + const i32_t LOG_ALLOW_INFO = 0x00000002; + const i32_t LOG_ALLOW_WARN = 0x00000004; + const i32_t LOG_ALLOW_ERROR = 0x00000008; + const i32_t LOG_ALLOW_NOTICE = 0x00000010; + const i32_t LOG_ALLOW_ALERT = 0x00000020; + const i32_t LOG_ALLOW_CRIT = 0x00000040; + + const i32_t LOG_ALLOW_DEFAULT = 0x00008000; // show messages having an unknown type + const i32_t LOG_ALLOW_NONE = 0x00000000; + const i32_t LOG_ALLOW_MESSAGES = 0x0000ffff; + const i32_t LOG_ALLOW_ANY = 0xffffffff; + + // A log message with environmental metadata + class LogEntry : public IArchive + { + public: + ui32_t PID; + Timestamp EventTime; + LogType_t Type; + std::string Msg; + + LogEntry() {} + LogEntry(ui32_t pid, LogType_t t, const char* m) : PID(pid), Type(t), Msg(m) { assert(m); } + virtual ~LogEntry() {} + + bool CreateStringWithFilter(i32_t, std::string&) const; + + // IArchive + bool HasValue() const { return ! Msg.empty(); } + ui32_t ArchiveLength() const; + bool Archive(MemIOWriter* Writer) const; + bool Unarchive(MemIOReader* Reader); + }; + + + typedef ArchivableList LogEntryList_t; + + // class ILogSink { - public: - enum LogType_t { LOG_DEBUG, LOG_INFO, LOG_WARN, LOG_ERROR, - LOG_NOTICE, LOG_ALERT, LOG_CRIT }; + protected: + i32_t m_filter; + public: virtual ~ILogSink() {} - void Critical(const char* fmt, ...) { LOG_MSG_IMPL(LOG_CRIT); } - void Alert(const char* fmt, ...) { LOG_MSG_IMPL(LOG_ALERT); } - void Notice(const char* fmt, ...) { LOG_MSG_IMPL(LOG_NOTICE); } + void SetFilterFlags(i32_t f) { m_filter = f; } + i32_t GetFilterFlags() const { return m_filter; } + void SetFilterFlag(i32_t f) { m_filter |= f; } + void UnsetFilterFlag(i32_t f) { m_filter &= ~f; } + bool TestFilterFlag(i32_t f) const { return ((m_filter & f) != 0); } + + // library messages void Error(const char* fmt, ...) { LOG_MSG_IMPL(LOG_ERROR); } void Warn(const char* fmt, ...) { LOG_MSG_IMPL(LOG_WARN); } void Info(const char* fmt, ...) { LOG_MSG_IMPL(LOG_INFO); } void Debug(const char* fmt, ...) { LOG_MSG_IMPL(LOG_DEBUG); } - void Logf(ILogSink::LogType_t type, const char* fmt, ...) { LOG_MSG_IMPL(type); } - virtual void vLogf(LogType_t, const char*, va_list*) = 0; // log a formatted string with a va_list struct + + // application messages + void Critical(const char* fmt, ...) { LOG_MSG_IMPL(LOG_CRIT); } + void Alert(const char* fmt, ...) { LOG_MSG_IMPL(LOG_ALERT); } + void Notice(const char* fmt, ...) { LOG_MSG_IMPL(LOG_NOTICE); } + + // message with type + void Logf(LogType_t type, const char* fmt, ...) { LOG_MSG_IMPL(type); } + + // actual log sink input + virtual void vLogf(LogType_t, const char*, va_list*); + virtual void WriteEntry(const LogEntry&) = 0; }; + // Sets the internal default sink to the given receiver. If the given value // is zero, sets the default sink to the internally allocated stderr sink. void SetDefaultLogSink(ILogSink* = 0); @@ -100,7 +174,67 @@ namespace Kumu // Returns the internal default sink. ILogSink& DefaultLogSink(); + + // Sets a log sink as the default until the object is destroyed. + // The original default sink is saved and then restored on delete. + class LogSinkContext + { + KM_NO_COPY_CONSTRUCT(LogSinkContext); + LogSinkContext(); + ILogSink* m_orig; + + public: + LogSinkContext(ILogSink& sink) { + m_orig = &DefaultLogSink(); + SetDefaultLogSink(&sink); + } + + ~LogSinkContext() { + SetDefaultLogSink(m_orig); + } + }; + + //------------------------------------------------------------------------------------------ // + + // write messages to two subordinate log sinks + class TeeLogSink : public ILogSink + { + KM_NO_COPY_CONSTRUCT(TeeLogSink); + TeeLogSink(); + + ILogSink& m_a; + ILogSink& m_b; + + public: + TeeLogSink(ILogSink& a, ILogSink& b) : m_a(a), m_b(b) {} + virtual ~TeeLogSink() {} + + void WriteEntry(const LogEntry& Entry) { + m_a.WriteEntry(Entry); + m_a.WriteEntry(Entry); + } + }; + + // collect log messages into the given list + class EntryListLogSink : public ILogSink + { + KM_NO_COPY_CONSTRUCT(EntryListLogSink); + EntryListLogSink(); + + LogEntryList_t& m_Target; + + public: + EntryListLogSink(LogEntryList_t& target) : m_Target(target) {} + virtual ~EntryListLogSink() {} + + void WriteEntry(const LogEntry& Entry) { + m_Target.push_back(Entry); + } + }; + + + // write messages to a POSIX stdio stream class StdioLogSink : public ILogSink { Mutex m_Lock; @@ -111,11 +245,12 @@ namespace Kumu StdioLogSink() : m_stream(stderr) {}; StdioLogSink(FILE* stream) : m_stream(stream) {} virtual ~StdioLogSink() {} - virtual void vLogf(LogType_t, const char*, va_list*); + + void WriteEntry(const LogEntry&); }; #ifdef KM_WIN32 - // + // write messages to the Win32 debug stream class WinDbgLogSink : public ILogSink { Mutex m_Lock; @@ -124,12 +259,13 @@ namespace Kumu public: WinDbgLogSink() {} virtual ~WinDbgLogSink() {} - virtual void vLogf(LogType_t, const char*, va_list*); - }; -#else + void WriteEntry(const LogEntry&); + }; +#endif - // +#ifndef KM_WIN32 + // write messages to a POSIX file descriptor class StreamLogSink : public ILogSink { Mutex m_Lock; @@ -140,10 +276,12 @@ namespace Kumu public: StreamLogSink(int fd) : m_fd(fd) {} virtual ~StreamLogSink() {} - virtual void vLogf(LogType_t, const char*, va_list*); + + void WriteEntry(const LogEntry&); }; #endif + } // namespace Kumu #endif // _KM_LOG_H_ diff --git a/src/KM_memio.h b/src/KM_memio.h index 483bbde..c034e82 100755 --- a/src/KM_memio.h +++ b/src/KM_memio.h @@ -1,5 +1,5 @@ /* -Copyright (c) 2006, John Hurst +Copyright (c) 2006-2007, John Hurst All rights reserved. Redistribution and use in source and binary forms, with or without @@ -61,8 +61,8 @@ namespace Kumu inline void Reset() { m_size = 0; } inline byte_t* Data() { return m_p; } inline byte_t* CurrentData() { return m_p + m_size; } - inline ui32_t Length() { return m_size; } - inline ui32_t Remainder() { return m_capacity - m_size; } + inline ui32_t Length() { return m_size; } + inline ui32_t Remainder() { return m_capacity - m_size; } inline bool AddOffset(ui32_t offset) { if ( ( m_size + offset ) > m_capacity ) diff --git a/src/KM_util.cpp b/src/KM_util.cpp index 76b7939..d1e82e1 100755 --- a/src/KM_util.cpp +++ b/src/KM_util.cpp @@ -49,7 +49,7 @@ struct map_entry_t Kumu::Result_t* result; }; -const ui32_t MapMax = 512; +const ui32_t MapMax = 1024; const ui32_t MapSize = MapMax * (sizeof(struct map_entry_t)); static bool s_MapInit = false; static struct map_entry_t s_ResultMap[MapSize]; @@ -71,10 +71,39 @@ Kumu::Result_t::Find(int v) return RESULT_FAIL; } +// +Kumu::Result_t +Kumu::Result_t::Delete(int v) +{ + if ( v >= RESULT_NOTAFILE.Value() ) + { + DefaultLogSink().Error("Cannot delete core result code: %ld\n", v); + return RESULT_FAIL; + } + + for ( ui32_t i = 0; s_ResultMap[i].result != 0 && i < MapMax; i++ ) + { + if ( s_ResultMap[i].rcode == v ) + { + s_ResultMap[i].rcode = 0; + s_ResultMap[i++].result = 0; + + for ( ; s_ResultMap[i].result != 0 && i < MapMax; i++ ) + s_ResultMap[i-1] = s_ResultMap[i]; + + return RESULT_OK; + } + } + + return RESULT_FALSE; +} + + // Kumu::Result_t::Result_t(int v, const char* l) : value(v), label(l) { assert(l); + assert(value < (int)MapMax); if ( v == 0 ) return; @@ -875,6 +904,15 @@ Kumu::Timestamp::DecodeString(const char* datestr) TmpStamp.Second = atoi(datestr + 17); } + if ( datestr[19] == '.' ) + { + if ( ! ( isdigit(datestr[20]) && isdigit(datestr[21]) && isdigit(datestr[22]) ) ) + return false; + + // we don't carry the ms value + datestr += 4; + } + if ( datestr[19] == '-' || datestr[19] == '+' ) { if ( ! ( isdigit(datestr[20]) && isdigit(datestr[21]) ) @@ -1047,24 +1085,32 @@ Kumu::ByteString::Set(const ByteString& Buf) // Sets the size of the internally allocate buffer. -// Resets content length to zero. Kumu::Result_t Kumu::ByteString::Capacity(ui32_t cap_size) { - if ( m_Capacity < cap_size ) + if ( m_Capacity >= cap_size ) + return RESULT_OK; + + byte_t* tmp_data = 0; + if ( m_Data != 0 ) { - if ( m_Data != 0 ) + if ( m_Length > 0 ) + tmp_data = m_Data; + else free(m_Data); + } - m_Data = (byte_t*)malloc(cap_size); - - if ( m_Data == 0 ) - return RESULT_ALLOC; - - m_Capacity = cap_size; - m_Length = 0; + if ( ( m_Data = (byte_t*)malloc(cap_size) ) == 0 ) + return RESULT_ALLOC; + + if ( tmp_data != 0 ) + { + assert(m_Length > 0); + memcpy(m_Data, tmp_data, m_Length); + free(tmp_data); } - + + m_Capacity = cap_size; return RESULT_OK; } diff --git a/src/KM_util.h b/src/KM_util.h index 244fc45..f7176f6 100755 --- a/src/KM_util.h +++ b/src/KM_util.h @@ -1,5 +1,5 @@ /* -Copyright (c) 2005-2006, John Hurst +Copyright (c) 2005-2007, John Hurst All rights reserved. Redistribution and use in source and binary forms, with or without @@ -170,11 +170,59 @@ namespace Kumu { public: virtual ~IArchive(){} - virtual bool HasValue() const = 0; - virtual bool Archive(MemIOWriter* Writer) const = 0; - virtual bool Unarchive(MemIOReader* Reader) = 0; + virtual bool HasValue() const = 0; + virtual ui32_t ArchiveLength() const = 0; + virtual bool Archive(MemIOWriter* Writer) const = 0; + virtual bool Unarchive(MemIOReader* Reader) = 0; }; + // + template + class ArchivableList : public std::list, public IArchive + { + public: + ArchivableList() {} + virtual ~ArchivableList() {} + + bool HasValue() const { return ! this->empty(); } + + ui32_t ArchiveLength() const + { + ui32_t arch_size = sizeof(ui32_t); + + typename ArchivableList::const_iterator i = this->begin(); + for ( ; i != this->end(); i++ ) + arch_size += i->ArchiveLength(); + + return arch_size; + } + + bool Unarchive(Kumu::MemIOReader* Reader) + { + if ( Reader == 0 ) return false; + ui32_t read_size = 0; + if ( ! Reader->ReadUi32BE(&read_size) ) return false; + for ( ui32_t i = 0; i < read_size; i++ ) + { + T TmpTP; + if ( ! TmpTP.Unarchive(Reader) ) return false; + this->push_back(TmpTP); + } + + return true; + } + + bool Archive(Kumu::MemIOWriter* Writer) const + { + if ( Writer == 0 ) return false; + if ( ! Writer->WriteUi32BE(this->size()) ) return false; + typename ArchivableList::const_iterator i = this->begin(); + for ( ; i != this->end(); i++ ) + if ( ! i->Archive(Writer) ) return false; + + return true; + } + }; // // the base of all identifier classes, Identifier is not usually used directly @@ -256,6 +304,8 @@ namespace Kumu inline bool HasValue() const { return m_HasValue; } + inline ui32_t ArchiveLength() const { return SIZE; } + inline bool Unarchive(Kumu::MemIOReader* Reader) { m_HasValue = Reader->ReadRaw(m_Value, SIZE); return m_HasValue; @@ -266,42 +316,6 @@ namespace Kumu } }; - // - template - class IdentifierList : public std::list, public IArchive - { - public: - IdentifierList() {} - virtual ~IdentifierList() {} - - bool HasValue() const { return ! this->empty(); } - - bool Unarchive(Kumu::MemIOReader* Reader) - { - if ( Reader == 0 )return false; - ui32_t read_size = 0; - if ( ! Reader->ReadUi32BE(&read_size) ) return false; - for ( ui32_t i = 0; i < read_size; i++ ) - { - T TmpTP; - if ( ! TmpTP.Unarchive(Reader) ) return false; - this->push_back(TmpTP); - } - - return true; - } - - bool Archive(Kumu::MemIOWriter* Writer) const - { - if ( Writer == 0 )return false; - if ( ! Writer->WriteUi32BE(this->size()) ) return false; - typename IdentifierList::const_iterator i = this->begin(); - for ( ; i != this->end(); i++ ) - if ( ! (*i).Archive(Writer) ) return false; - - return true; - } - }; // UUID // @@ -388,9 +402,10 @@ namespace Kumu // | 16 bits int, big-endian | 8 bits | 8 bits | 8 bits | 8 bits | 8 bits | // | Year A.D | Month(1-12) | Day(1-31) | Hour(0-23) | Minute(0-59) | Second(0-59) | // - virtual bool HasValue() const; - virtual bool Archive(MemIOWriter* Writer) const; - virtual bool Unarchive(MemIOReader* Reader); + virtual bool HasValue() const; + virtual ui32_t ArchiveLength() const { return 8L; } + virtual bool Archive(MemIOWriter* Writer) const; + virtual bool Unarchive(MemIOReader* Reader); }; // @@ -408,8 +423,7 @@ namespace Kumu ByteString(ui32_t cap); virtual ~ByteString(); - // Sets the size of the internally allocated buffer. - // Resets content Size to zero. + // Sets or resets the size of the internally allocated buffer. Result_t Capacity(ui32_t cap); Result_t Append(const ByteString&); @@ -437,6 +451,8 @@ namespace Kumu inline virtual bool HasValue() const { return m_Length > 0; } + inline virtual ui32_t ArchiveLength() const { return m_Length; } + inline virtual bool Archive(MemIOWriter* Writer) const { assert(Writer); if ( ! Writer->WriteUi32BE(m_Length) ) return false; diff --git a/src/MDD.cpp b/src/MDD.cpp index c7ddd7c..a88fa81 100644 --- a/src/MDD.cpp +++ b/src/MDD.cpp @@ -798,39 +798,39 @@ static const ASDCP::MDDEntry s_MDD_Table[] = { { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x09, // 254 0x02, 0x09, 0x03, 0x01, 0x02, 0x00, 0x00, 0x00 }, {0}, false, "CryptographicContext_CryptographicKeyID" }, - { { 0x06, 0x0e, 0x2b, 0x34, 0x00, 0x01, 0x01, 0x01, // 255 - 0x0d, 0x01, 0x03, 0x01, 0xfa, 0xce, 0x00, 0x00 }, - {0}, false, "DCTimedTextWrapping" }, - { { 0x06, 0x0e, 0x2b, 0x34, 0x00, 0x01, 0x01, 0x01, // 256 - 0x0d, 0x01, 0x03, 0x01, 0xfa, 0xce, 0x00, 0x01 }, - {0}, false, "DCTimedTextEssence" }, - { { 0x06, 0x0e, 0x2b, 0x34, 0x00, 0x01, 0x01, 0x01, // 257 - 0x0d, 0x01, 0x03, 0x01, 0xfa, 0xce, 0x00, 0x02 }, - {0}, false, "DCTimedTextDescriptor" }, - { { 0x06, 0x0e, 0x2b, 0x34, 0x00, 0x01, 0x01, 0x01, // 258 - 0x0d, 0x01, 0x03, 0x01, 0xfa, 0xce, 0x00, 0x03 }, - {0}, false, "DCTimedTextDescriptor_ResourceID" }, - { { 0x06, 0x0e, 0x2b, 0x34, 0x00, 0x01, 0x01, 0x01, // 259 - 0x0d, 0x01, 0x03, 0x01, 0xfa, 0xce, 0x00, 0x04 }, - {0}, false, "DCTimedTextDescriptor_UTFEncoding" }, - { { 0x06, 0x0e, 0x2b, 0x34, 0x00, 0x01, 0x01, 0x01, // 260 - 0x0d, 0x01, 0x03, 0x01, 0xfa, 0xce, 0x00, 0x05 }, - {0}, false, "DCTimedTextDescriptor_RootNamespaceName" }, - { { 0x06, 0x0e, 0x2b, 0x34, 0x00, 0x01, 0x01, 0x01, // 261 - 0x0d, 0x01, 0x03, 0x01, 0xfa, 0xce, 0x00, 0x06 }, - {0}, false, "DCTimedTextResourceDescriptor" }, - { { 0x06, 0x0e, 0x2b, 0x34, 0x00, 0x01, 0x01, 0x01, // 262 - 0x0d, 0x01, 0x03, 0x01, 0xfa, 0xce, 0x00, 0x07 }, - {0}, false, "DCTimedTextResourceDescriptor_ResourceID" }, - { { 0x06, 0x0e, 0x2b, 0x34, 0x00, 0x01, 0x01, 0x01, // 263 - 0x0d, 0x01, 0x03, 0x01, 0xfa, 0xce, 0x00, 0x08 }, - {0}, false, "DCTimedTextResourceDescriptor_ResourceMIMEType" }, - { { 0x06, 0x0e, 0x2b, 0x34, 0x00, 0x01, 0x01, 0x01, // 264 - 0x0d, 0x01, 0x03, 0x01, 0xfa, 0xce, 0x00, 0x09 }, - {0}, false, "DCTimedTextResourceDescriptor_ResourceSID" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x09, // 255 + 0x0d, 0x01, 0x03, 0x01, 0x02, 0x13, 0x01, 0x01 }, + {0}, false, "TimedTextWrapping" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x02, 0x01, 0x09, // 256 + 0x0d, 0x01, 0x03, 0x01, 0x17, 0x01, 0x0b, 0x01 }, + {0}, false, "TimedTextEssence" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x02, 0x7f, 0x01, 0x01, // 257 + 0x0d, 0x01, 0x01, 0x01, 0x01, 0x01, 0x64, 0x00 }, + {0}, false, "TimedTextDescriptor" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x0c, // 258 + 0x01, 0x01, 0x15, 0x12, 0x00, 0x00, 0x00, 0x00 }, + {0}, false, "TimedTextDescriptor_ResourceID" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x0c, // 259 + 0x04, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00 }, + {0}, false, "TimedTextDescriptor_UCSEncoding" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x08, // 260 + 0x01, 0x02, 0x01, 0x05, 0x01, 0x00, 0x00, 0x00 }, + {0}, false, "TimedTextDescriptor_NamespaceURI" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x02, 0x7f, 0x01, 0x01, // 261 + 0x0d, 0x01, 0x01, 0x01, 0x01, 0x01, 0x65, 0x00 }, + {0}, false, "TimedTextResourceSubDescriptor" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x0c, // 262 + 0x01, 0x01, 0x15, 0x13, 0x00, 0x00, 0x00, 0x00 }, + {0}, false, "TimedTextResourceSubDescriptor_AncillaryResourceID" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x07, // 263 + 0x04, 0x09, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00 }, + {0}, false, "TimedTextResourceSubDescriptor_MIMEMediaType" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, // 264 + 0x01, 0x03, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00 }, + {0}, false, "TimedTextResourceSubDescriptor_EssenceStreamID" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, // 265 0x06, 0x10, 0x10, 0x05, 0x01, 0x02, 0x11, 0x00 }, - {0}, false, "GenericStreamPartition" }, + {0}, false, "GenericStreamPartition" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02, // 266 0x04, 0x07, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 }, {0x02, 0x01}, false, "DMSegment_DataDefinition" }, @@ -840,9 +840,10 @@ static const ASDCP::MDDEntry s_MDD_Table[] = { { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02, // 268 0x01, 0x07, 0x01, 0x05, 0x00, 0x00, 0x00, 0x00 }, {0x61, 0x02}, false, "DMSegment_TrackIDList" }, - { { 0x06, 0x0e, 0x2b, 0x34, 0x00, 0x01, 0x01, 0x01, // 269 - 0x0d, 0x01, 0x03, 0x01, 0xfa, 0xce, 0x00, 0xf6 }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x02, 0x7f, 0x01, 0x01, // 269 + 0x0d, 0x01, 0x01, 0x01, 0x01, 0x01, 0x71, 0x00 }, {0}, false, "StereoscopicPictureSubDescriptor" }, + { {0}, {0}, false, 0 } }; diff --git a/src/MDD.h b/src/MDD.h index 4218f9d..e3145f5 100755 --- a/src/MDD.h +++ b/src/MDD.h @@ -290,21 +290,22 @@ namespace ASDCP { MDD_CryptographicContext_CipherAlgorithm, // 252 MDD_CryptographicContext_MICAlgorithm, // 253 MDD_CryptographicContext_CryptographicKeyID, // 254 - MDD_DCTimedTextWrapping, // 255 - MDD_DCTimedTextEssence, // 256 - MDD_DCTimedTextDescriptor, // 257 - MDD_DCTimedTextDescriptor_ResourceID, // 258 - MDD_DCTimedTextDescriptor_UTFEncoding, // 259 - MDD_DCTimedTextDescriptor_RootNamespaceName, // 260 - MDD_DCTimedTextResourceDescriptor, // 261 - MDD_DCTimedTextResourceDescriptor_ResourceID, // 262 - MDD_DCTimedTextResourceDescriptor_ResourceMIMEType, // 263 - MDD_DCTimedTextResourceDescriptor_ResourceSID, // 264 + MDD_TimedTextWrapping, // 255 + MDD_TimedTextEssence, // 256 + MDD_TimedTextDescriptor, // 257 + MDD_TimedTextDescriptor_ResourceID, // 258 + MDD_TimedTextDescriptor_UCSEncoding, // 259 + MDD_TimedTextDescriptor_NamespaceURI, // 260 + MDD_TimedTextResourceSubDescriptor, // 261 + MDD_TimedTextResourceSubDescriptor_AncillaryResourceID, // 262 + MDD_TimedTextResourceSubDescriptor_MIMEMediaType, // 263 + MDD_TimedTextResourceSubDescriptor_EssenceStreamID, // 264 MDD_GenericStreamPartition, // 265 MDD_DMSegment_DataDefinition, // 266 MDD_DMSegment_Duration, // 267 MDD_DMSegment_TrackIDList, // 268 MDD_StereoscopicPictureSubDescriptor, // 269 + MDD_Max, }; // enum MDD_t } // namespaceASDCP diff --git a/src/MXF.h b/src/MXF.h index f3c2449..6a9b14d 100755 --- a/src/MXF.h +++ b/src/MXF.h @@ -78,15 +78,16 @@ namespace ASDCP return str_buf; } - inline virtual bool Unarchive(Kumu::MemIOReader* Reader) { + inline bool HasValue() const { return true; } + inline ui32_t ArchiveLength() const { return sizeof(ui32_t) + sizeof(ui64_t); } + + inline bool Unarchive(Kumu::MemIOReader* Reader) { if ( ! Reader->ReadUi32BE(&BodySID) ) return false; if ( ! Reader->ReadUi64BE(&ByteOffset) ) return false; return true; } - inline virtual bool HasValue() const { return true; } - - inline virtual bool Archive(Kumu::MemIOWriter* Writer) const { + inline bool Archive(Kumu::MemIOWriter* Writer) const { if ( ! Writer->WriteUi32BE(BodySID) ) return false; if ( ! Writer->WriteUi64BE(ByteOffset) ) return false; return true; @@ -148,7 +149,7 @@ namespace ASDCP public: // - class LocalTagEntry + class LocalTagEntry : Kumu::IArchive { public: TagValue Tag; @@ -160,6 +161,9 @@ namespace ASDCP return str_buf; } + inline bool HasValue() const { return UL.HasValue(); } + inline ui32_t ArchiveLength() const { return 2 + UL.ArchiveLength(); } + inline bool Unarchive(Kumu::MemIOReader* Reader) { if ( ! Reader->ReadUi8(&Tag.a) ) return false; if ( ! Reader->ReadUi8(&Tag.b) ) return false; @@ -246,7 +250,7 @@ namespace ASDCP public: // - class DeltaEntry + class DeltaEntry : public Kumu::IArchive { public: i8_t PosTableIndex; @@ -254,13 +258,15 @@ namespace ASDCP ui32_t ElementData; DeltaEntry() : PosTableIndex(-1), Slice(0), ElementData(0) {} + inline bool HasValue() const { return true; } + ui32_t ArchiveLength() const { return sizeof(ui32_t) + 2; } bool Unarchive(Kumu::MemIOReader* Reader); bool Archive(Kumu::MemIOWriter* Writer) const; const char* EncodeString(char* str_buf, ui32_t buf_len) const; }; // - class IndexEntry + class IndexEntry : public Kumu::IArchive { public: i8_t TemporalOffset; @@ -274,6 +280,8 @@ namespace ASDCP // Array PosTable; IndexEntry() : TemporalOffset(0), KeyFrameOffset(0), Flags(0), StreamOffset() {} + inline bool HasValue() const { return true; } + ui32_t ArchiveLength() const { return sizeof(ui64_t) + 3; }; bool Unarchive(Kumu::MemIOReader* Reader); bool Archive(Kumu::MemIOWriter* Writer) const; const char* EncodeString(char* str_buf, ui32_t buf_len) const; diff --git a/src/MXFTypes.h b/src/MXFTypes.h index c6617aa..1fa6176 100755 --- a/src/MXFTypes.h +++ b/src/MXFTypes.h @@ -125,6 +125,18 @@ namespace ASDCP inline virtual bool HasValue() const { return ! this->empty(); } + virtual ui32_t ArchiveLength() const { + ui32_t arch_size = sizeof(ui32_t)*2; + + typename std::vector::const_iterator l_i = this->begin(); + assert(l_i != this->end()); + + for ( ; l_i != this->end(); l_i++ ) + arch_size += l_i->ArchiveLength(); + + return arch_size; + } + // virtual bool Archive(Kumu::MemIOWriter* Writer) const { if ( ! Writer->WriteUi32BE(this->size()) ) return false; @@ -188,6 +200,17 @@ namespace ASDCP inline virtual bool HasValue() const { return ! this->empty(); } + virtual ui32_t ArchiveLength() const { + ui32_t arch_size = 0; + + typename std::list::const_iterator l_i = this->begin(); + + for ( ; l_i != this->end(); l_i++ ) + arch_size += l_i->ArchiveLength(); + + return arch_size; + } + // virtual bool Archive(Kumu::MemIOWriter* Writer) const { bool result = true; @@ -255,6 +278,7 @@ namespace ASDCP } inline virtual bool HasValue() const { return true; } + inline virtual ui32_t ArchiveLength() const { return 8L; } // inline virtual bool Archive(Kumu::MemIOWriter* Writer) const { @@ -275,8 +299,9 @@ namespace ASDCP const UTF16String& operator=(const std::string&); const char* EncodeString(char* str_buf, ui32_t buf_len) const; - virtual bool Unarchive(Kumu::MemIOReader* Reader); inline virtual bool HasValue() const { return ! empty(); } + inline virtual ui32_t ArchiveLength() const { return sizeof(ui32_t) + size(); } + virtual bool Unarchive(Kumu::MemIOReader* Reader); virtual bool Archive(Kumu::MemIOWriter* Writer) const; }; @@ -322,6 +347,7 @@ namespace ASDCP } inline virtual bool HasValue() const { return true; } + inline virtual ui32_t ArchiveLength() const { return sizeof(ui32_t)*2; } inline virtual bool Archive(Kumu::MemIOWriter* Writer) const { if ( ! Writer->WriteUi32BE((ui32_t)Numerator) ) return false; @@ -341,7 +367,7 @@ namespace ASDCP ui16_t Minor; ui16_t Patch; ui16_t Build; - ui16_t Release; + Release_t Release; VersionType() : Major(0), Minor(0), Patch(0), Build(0), Release(RL_UNKNOWN) {} ~VersionType() {} @@ -364,6 +390,7 @@ namespace ASDCP } inline virtual bool HasValue() const { return true; } + inline virtual ui32_t ArchiveLength() const { return sizeof(ui16_t)*5; } virtual bool Archive(Kumu::MemIOWriter* Writer) const { if ( ! Writer->WriteUi16BE(Major) ) return false; diff --git a/src/Metadata.cpp b/src/Metadata.cpp index c9eb689..838fc53 100755 --- a/src/Metadata.cpp +++ b/src/Metadata.cpp @@ -65,8 +65,8 @@ static InterchangeObject* DMSegment_Factory() { return new DMSegment; } static InterchangeObject* CryptographicFramework_Factory() { return new CryptographicFramework; } static InterchangeObject* CryptographicContext_Factory() { return new CryptographicContext; } static InterchangeObject* GenericDataEssenceDescriptor_Factory() { return new GenericDataEssenceDescriptor; } -static InterchangeObject* DCTimedTextDescriptor_Factory() { return new DCTimedTextDescriptor; } -static InterchangeObject* DCTimedTextResourceDescriptor_Factory() { return new DCTimedTextResourceDescriptor; } +static InterchangeObject* TimedTextDescriptor_Factory() { return new TimedTextDescriptor; } +static InterchangeObject* TimedTextResourceSubDescriptor_Factory() { return new TimedTextResourceSubDescriptor; } static InterchangeObject* StereoscopicPictureSubDescriptor_Factory() { return new StereoscopicPictureSubDescriptor; } @@ -98,8 +98,8 @@ ASDCP::MXF::Metadata_InitTypes() SetObjectFactory(Dict::ul(MDD_CryptographicFramework), CryptographicFramework_Factory); SetObjectFactory(Dict::ul(MDD_CryptographicContext), CryptographicContext_Factory); SetObjectFactory(Dict::ul(MDD_GenericDataEssenceDescriptor), GenericDataEssenceDescriptor_Factory); - SetObjectFactory(Dict::ul(MDD_DCTimedTextDescriptor), DCTimedTextDescriptor_Factory); - SetObjectFactory(Dict::ul(MDD_DCTimedTextResourceDescriptor), DCTimedTextResourceDescriptor_Factory); + SetObjectFactory(Dict::ul(MDD_TimedTextDescriptor), TimedTextDescriptor_Factory); + SetObjectFactory(Dict::ul(MDD_TimedTextResourceSubDescriptor), TimedTextResourceSubDescriptor_Factory); SetObjectFactory(Dict::ul(MDD_StereoscopicPictureSubDescriptor), StereoscopicPictureSubDescriptor_Factory); } @@ -1035,6 +1035,7 @@ GenericPictureEssenceDescriptor::InitFromTLVSet(TLVReader& TLVSet) if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadUi32(OBJ_READ_ARGS(GenericPictureEssenceDescriptor, StoredWidth)); if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadUi32(OBJ_READ_ARGS(GenericPictureEssenceDescriptor, StoredHeight)); if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadObject(OBJ_READ_ARGS(GenericPictureEssenceDescriptor, AspectRatio)); + if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadObject(OBJ_READ_ARGS(GenericPictureEssenceDescriptor, PictureEssenceCoding)); return result; } @@ -1047,6 +1048,7 @@ GenericPictureEssenceDescriptor::WriteToTLVSet(TLVWriter& TLVSet) if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteUi32(OBJ_WRITE_ARGS(GenericPictureEssenceDescriptor, StoredWidth)); if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteUi32(OBJ_WRITE_ARGS(GenericPictureEssenceDescriptor, StoredHeight)); if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS(GenericPictureEssenceDescriptor, AspectRatio)); + if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS(GenericPictureEssenceDescriptor, PictureEssenceCoding)); return result; } @@ -1065,6 +1067,7 @@ GenericPictureEssenceDescriptor::Dump(FILE* stream) fprintf(stream, " %22s = %d\n", "StoredWidth", StoredWidth); fprintf(stream, " %22s = %d\n", "StoredHeight", StoredHeight); fprintf(stream, " %22s = %s\n", "AspectRatio", AspectRatio.EncodeString(identbuf, IdentBufferLen)); + fprintf(stream, " %22s = %s\n", "PictureEssenceCoding", PictureEssenceCoding.EncodeString(identbuf, IdentBufferLen)); } // @@ -1573,33 +1576,33 @@ GenericDataEssenceDescriptor::WriteToBuffer(ASDCP::FrameBuffer& Buffer) } //------------------------------------------------------------------------------------------ -// DCTimedTextDescriptor +// TimedTextDescriptor // ASDCP::Result_t -DCTimedTextDescriptor::InitFromTLVSet(TLVReader& TLVSet) +TimedTextDescriptor::InitFromTLVSet(TLVReader& TLVSet) { Result_t result = GenericDataEssenceDescriptor::InitFromTLVSet(TLVSet); - if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadObject(OBJ_READ_ARGS(DCTimedTextDescriptor, ResourceID)); - if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadObject(OBJ_READ_ARGS(DCTimedTextDescriptor, UTFEncoding)); - if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadObject(OBJ_READ_ARGS(DCTimedTextDescriptor, RootNamespaceName)); + if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadObject(OBJ_READ_ARGS(TimedTextDescriptor, ResourceID)); + if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadObject(OBJ_READ_ARGS(TimedTextDescriptor, UCSEncoding)); + if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadObject(OBJ_READ_ARGS(TimedTextDescriptor, NamespaceURI)); return result; } // ASDCP::Result_t -DCTimedTextDescriptor::WriteToTLVSet(TLVWriter& TLVSet) +TimedTextDescriptor::WriteToTLVSet(TLVWriter& TLVSet) { Result_t result = GenericDataEssenceDescriptor::WriteToTLVSet(TLVSet); - if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS(DCTimedTextDescriptor, ResourceID)); - if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS(DCTimedTextDescriptor, UTFEncoding)); - if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS(DCTimedTextDescriptor, RootNamespaceName)); + if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS(TimedTextDescriptor, ResourceID)); + if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS(TimedTextDescriptor, UCSEncoding)); + if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS(TimedTextDescriptor, NamespaceURI)); return result; } // void -DCTimedTextDescriptor::Dump(FILE* stream) +TimedTextDescriptor::Dump(FILE* stream) { char identbuf[IdentBufferLen]; *identbuf = 0; @@ -1609,54 +1612,54 @@ DCTimedTextDescriptor::Dump(FILE* stream) GenericDataEssenceDescriptor::Dump(stream); fprintf(stream, " %22s = %s\n", "ResourceID", ResourceID.EncodeString(identbuf, IdentBufferLen)); - fprintf(stream, " %22s = %s\n", "UTFEncoding", UTFEncoding.EncodeString(identbuf, IdentBufferLen)); - fprintf(stream, " %22s = %s\n", "RootNamespaceName", RootNamespaceName.EncodeString(identbuf, IdentBufferLen)); + fprintf(stream, " %22s = %s\n", "UCSEncoding", UCSEncoding.EncodeString(identbuf, IdentBufferLen)); + fprintf(stream, " %22s = %s\n", "NamespaceURI", NamespaceURI.EncodeString(identbuf, IdentBufferLen)); } // ASDCP::Result_t -DCTimedTextDescriptor::InitFromBuffer(const byte_t* p, ui32_t l) +TimedTextDescriptor::InitFromBuffer(const byte_t* p, ui32_t l) { - m_Typeinfo = &Dict::Type(MDD_DCTimedTextDescriptor); + m_Typeinfo = &Dict::Type(MDD_TimedTextDescriptor); return InterchangeObject::InitFromBuffer(p, l); } // ASDCP::Result_t -DCTimedTextDescriptor::WriteToBuffer(ASDCP::FrameBuffer& Buffer) +TimedTextDescriptor::WriteToBuffer(ASDCP::FrameBuffer& Buffer) { - m_Typeinfo = &Dict::Type(MDD_DCTimedTextDescriptor); + m_Typeinfo = &Dict::Type(MDD_TimedTextDescriptor); return InterchangeObject::WriteToBuffer(Buffer); } //------------------------------------------------------------------------------------------ -// DCTimedTextResourceDescriptor +// TimedTextResourceSubDescriptor // ASDCP::Result_t -DCTimedTextResourceDescriptor::InitFromTLVSet(TLVReader& TLVSet) +TimedTextResourceSubDescriptor::InitFromTLVSet(TLVReader& TLVSet) { Result_t result = InterchangeObject::InitFromTLVSet(TLVSet); - if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadObject(OBJ_READ_ARGS(DCTimedTextResourceDescriptor, ResourceID)); - if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadObject(OBJ_READ_ARGS(DCTimedTextResourceDescriptor, ResourceMIMEType)); - if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadUi32(OBJ_READ_ARGS(DCTimedTextResourceDescriptor, ResourceSID)); + if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadObject(OBJ_READ_ARGS(TimedTextResourceSubDescriptor, AncillaryResourceID)); + if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadObject(OBJ_READ_ARGS(TimedTextResourceSubDescriptor, MIMEMediaType)); + if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadUi32(OBJ_READ_ARGS(TimedTextResourceSubDescriptor, EssenceStreamID)); return result; } // ASDCP::Result_t -DCTimedTextResourceDescriptor::WriteToTLVSet(TLVWriter& TLVSet) +TimedTextResourceSubDescriptor::WriteToTLVSet(TLVWriter& TLVSet) { Result_t result = InterchangeObject::WriteToTLVSet(TLVSet); - if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS(DCTimedTextResourceDescriptor, ResourceID)); - if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS(DCTimedTextResourceDescriptor, ResourceMIMEType)); - if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteUi32(OBJ_WRITE_ARGS(DCTimedTextResourceDescriptor, ResourceSID)); + if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS(TimedTextResourceSubDescriptor, AncillaryResourceID)); + if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS(TimedTextResourceSubDescriptor, MIMEMediaType)); + if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteUi32(OBJ_WRITE_ARGS(TimedTextResourceSubDescriptor, EssenceStreamID)); return result; } // void -DCTimedTextResourceDescriptor::Dump(FILE* stream) +TimedTextResourceSubDescriptor::Dump(FILE* stream) { char identbuf[IdentBufferLen]; *identbuf = 0; @@ -1665,24 +1668,24 @@ DCTimedTextResourceDescriptor::Dump(FILE* stream) stream = stderr; InterchangeObject::Dump(stream); - fprintf(stream, " %22s = %s\n", "ResourceID", ResourceID.EncodeString(identbuf, IdentBufferLen)); - fprintf(stream, " %22s = %s\n", "ResourceMIMEType", ResourceMIMEType.EncodeString(identbuf, IdentBufferLen)); - fprintf(stream, " %22s = %d\n", "ResourceSID", ResourceSID); + fprintf(stream, " %22s = %s\n", "AncillaryResourceID", AncillaryResourceID.EncodeString(identbuf, IdentBufferLen)); + fprintf(stream, " %22s = %s\n", "MIMEMediaType", MIMEMediaType.EncodeString(identbuf, IdentBufferLen)); + fprintf(stream, " %22s = %d\n", "EssenceStreamID", EssenceStreamID); } // ASDCP::Result_t -DCTimedTextResourceDescriptor::InitFromBuffer(const byte_t* p, ui32_t l) +TimedTextResourceSubDescriptor::InitFromBuffer(const byte_t* p, ui32_t l) { - m_Typeinfo = &Dict::Type(MDD_DCTimedTextResourceDescriptor); + m_Typeinfo = &Dict::Type(MDD_TimedTextResourceSubDescriptor); return InterchangeObject::InitFromBuffer(p, l); } // ASDCP::Result_t -DCTimedTextResourceDescriptor::WriteToBuffer(ASDCP::FrameBuffer& Buffer) +TimedTextResourceSubDescriptor::WriteToBuffer(ASDCP::FrameBuffer& Buffer) { - m_Typeinfo = &Dict::Type(MDD_DCTimedTextResourceDescriptor); + m_Typeinfo = &Dict::Type(MDD_TimedTextResourceSubDescriptor); return InterchangeObject::WriteToBuffer(Buffer); } diff --git a/src/Metadata.h b/src/Metadata.h index bcd3b6f..207e031 100755 --- a/src/Metadata.h +++ b/src/Metadata.h @@ -384,6 +384,7 @@ namespace ASDCP ui32_t StoredWidth; ui32_t StoredHeight; Rational AspectRatio; + UL PictureEssenceCoding; GenericPictureEssenceDescriptor() : FrameLayout(0), StoredWidth(0), StoredHeight(0) {} virtual ~GenericPictureEssenceDescriptor() {} @@ -567,18 +568,18 @@ namespace ASDCP }; // - class DCTimedTextDescriptor : public GenericDataEssenceDescriptor + class TimedTextDescriptor : public GenericDataEssenceDescriptor { - ASDCP_NO_COPY_CONSTRUCT(DCTimedTextDescriptor); + ASDCP_NO_COPY_CONSTRUCT(TimedTextDescriptor); public: UUID ResourceID; - UTF16String UTFEncoding; - UTF16String RootNamespaceName; + UTF16String UCSEncoding; + UTF16String NamespaceURI; - DCTimedTextDescriptor() {} - virtual ~DCTimedTextDescriptor() {} - virtual const char* HasName() { return "DCTimedTextDescriptor"; } + TimedTextDescriptor() {} + virtual ~TimedTextDescriptor() {} + virtual const char* HasName() { return "TimedTextDescriptor"; } virtual Result_t InitFromTLVSet(TLVReader& TLVSet); virtual Result_t WriteToTLVSet(TLVWriter& TLVSet); virtual void Dump(FILE* = 0); @@ -587,18 +588,18 @@ namespace ASDCP }; // - class DCTimedTextResourceDescriptor : public InterchangeObject + class TimedTextResourceSubDescriptor : public InterchangeObject { - ASDCP_NO_COPY_CONSTRUCT(DCTimedTextResourceDescriptor); + ASDCP_NO_COPY_CONSTRUCT(TimedTextResourceSubDescriptor); public: - UUID ResourceID; - UTF16String ResourceMIMEType; - ui32_t ResourceSID; + UUID AncillaryResourceID; + UTF16String MIMEMediaType; + ui32_t EssenceStreamID; - DCTimedTextResourceDescriptor() : ResourceSID(0) {} - virtual ~DCTimedTextResourceDescriptor() {} - virtual const char* HasName() { return "DCTimedTextResourceDescriptor"; } + TimedTextResourceSubDescriptor() : EssenceStreamID(0) {} + virtual ~TimedTextResourceSubDescriptor() {} + virtual const char* HasName() { return "TimedTextResourceSubDescriptor"; } virtual Result_t InitFromTLVSet(TLVReader& TLVSet); virtual Result_t WriteToTLVSet(TLVWriter& TLVSet); virtual void Dump(FILE* = 0); diff --git a/src/S12MTimecode.h b/src/S12MTimecode.h index 23ccbb4..0a88528 100644 --- a/src/S12MTimecode.h +++ b/src/S12MTimecode.h @@ -130,6 +130,7 @@ public: // IArchive bool HasValue() const { return (m_FPS > 0); } + ui32_t ArchiveLength() const { return sizeof(ui32_t)*2; } bool Archive(Kumu::MemIOWriter* Writer) const { diff --git a/src/TimedText_Parser.cpp b/src/TimedText_Parser.cpp index 8595b31..8c31909 100644 --- a/src/TimedText_Parser.cpp +++ b/src/TimedText_Parser.cpp @@ -304,7 +304,7 @@ ASDCP::TimedText::DCSubtitleParser::h__SubtitleParser::ReadAncillaryResource(con FrameBuf.MIMEType("image/png"); else if ( (*rmi).second == MT_OPENTYPE ) - FrameBuf.MIMEType("application/x-opentype"); + FrameBuf.MIMEType("application/x-font-opentype"); else FrameBuf.MIMEType("application/octet-stream"); diff --git a/src/asdcp-test.cpp b/src/asdcp-test.cpp index ffd3246..eadfc76 100755 --- a/src/asdcp-test.cpp +++ b/src/asdcp-test.cpp @@ -151,6 +151,7 @@ Major modes:\n\ -h | -help - Show help\n\ -i - Show file info\n\ -t - Calculate message digest of input file\n\ + -U - Dump UL catalog to stdout\n\ -u - Generate a random UUID value to stdout\n\ -V - Show version information\n\ -x - Extract essence from AS-DCP file to named file(s)\n\ @@ -211,7 +212,8 @@ enum MajorMode_t MMT_GEN_ID, MMT_GEN_KEY, MMT_GOP_START, - MMT_DIGEST + MMT_DIGEST, + MMT_UL_LIST, }; @@ -310,6 +312,7 @@ public: case 'h': help_flag = true; break; case 'v': verbose_flag = true; break; case 'g': mode = MMT_GEN_KEY; break; + case 'U': mode = MMT_UL_LIST; break; case 'u': mode = MMT_GEN_ID; break; case 'e': encrypt_header_flag = true; break; case 'E': encrypt_header_flag = false; break; @@ -1752,6 +1755,7 @@ int main(int argc, const char** argv) { Result_t result = RESULT_OK; + char str_buf[64]; CommandOptions Options(argc, argv); if ( Options.version_flag ) @@ -1781,23 +1785,33 @@ main(int argc, const char** argv) { Kumu::FortunaRNG RNG; byte_t bin_buf[KeyLen]; - char str_buf[40]; RNG.FillRandom(bin_buf, KeyLen); - printf("%s\n", Kumu::bin2hex(bin_buf, KeyLen, str_buf, 40)); + printf("%s\n", Kumu::bin2hex(bin_buf, KeyLen, str_buf, 64)); } else if ( Options.mode == MMT_GEN_ID ) { UUID TmpID; Kumu::GenRandomValue(TmpID); - char str_buf[40]; - printf("%s\n", TmpID.EncodeHex(str_buf, 40)); + printf("%s\n", TmpID.EncodeHex(str_buf, 64)); } else if ( Options.mode == MMT_DIGEST ) { for ( ui32_t i = 0; i < Options.file_count && ASDCP_SUCCESS(result); i++ ) result = digest_file(Options.filenames[i]); } + else if ( Options.mode == MMT_UL_LIST ) + { + MDD_t di = (MDD_t)0; + + while ( di < MDD_Max ) + { + MDDEntry TmpType = Dict::Type(di); + UL TmpUL(TmpType.ul); + fprintf(stdout, "%s: %s\n", TmpUL.EncodeString(str_buf, 64), TmpType.name); + di = (MDD_t)(di + 1); + } + } else if ( Options.mode == MMT_EXTRACT ) { EssenceType_t EssenceType; @@ -1879,6 +1893,11 @@ main(int argc, const char** argv) } } } + else + { + fprintf(stderr, "Unhandled mode: %d.\n", Options.mode); + return 6; + } if ( ASDCP_FAILURE(result) ) { -- 2.30.2