summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjhurst <jhurst@cinecert.com>2007-12-22 19:32:35 +0000
committerjhurst <>2007-12-22 19:32:35 +0000
commit4564a68b8a586b49715f39fb84271db61fc109b7 (patch)
tree19630698bd75331739ec9ed9bc58c2bac19cd55b
parent9d3309c016ca46131373327e9d15cf5aa4fd8088 (diff)
logging re-write
-rwxr-xr-xREADME21
-rwxr-xr-xsrc/AS_DCP_JP2K.cpp21
-rwxr-xr-xsrc/AS_DCP_MXF.cpp2
-rw-r--r--src/AS_DCP_TimedText.cpp82
-rwxr-xr-xsrc/KM_error.h1
-rwxr-xr-xsrc/KM_log.cpp205
-rwxr-xr-xsrc/KM_log.h186
-rwxr-xr-xsrc/KM_memio.h6
-rwxr-xr-xsrc/KM_util.cpp70
-rwxr-xr-xsrc/KM_util.h106
-rw-r--r--src/MDD.cpp67
-rwxr-xr-xsrc/MDD.h21
-rwxr-xr-xsrc/MXF.h22
-rwxr-xr-xsrc/MXFTypes.h31
-rwxr-xr-xsrc/Metadata.cpp77
-rwxr-xr-xsrc/Metadata.h31
-rw-r--r--src/S12MTimecode.h1
-rw-r--r--src/TimedText_Parser.cpp2
-rwxr-xr-xsrc/asdcp-test.cpp29
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<UUID, UUID> 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<UUID>::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<DCTimedTextResourceDescriptor*>(tmp_iobj);
+ DescObject = static_cast<TimedTextResourceSubDescriptor*>(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<DCTimedTextDescriptor*>(tmp_iobj);
+ result = m_HeaderPart.GetMDObjectByType(OBJ_TYPE_ARGS(TimedTextDescriptor), &tmp_iobj);
+ m_EssenceDescriptor = static_cast<MXF::TimedTextDescriptor*>(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<DCTimedTextResourceDescriptor*>(tmp_iobj);
+ DescObject = static_cast<TimedTextResourceSubDescriptor*>(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 <unistd.h>
#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 <KM_platform.h>
#include <KM_mutex.h>
+#include <KM_util.h>
#include <stdarg.h>
#include <errno.h>
-#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<LogEntry> 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];
@@ -72,9 +72,38 @@ Kumu::Result_t::Find(int v)
}
//
+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 T>
+ class ArchivableList : public std::list<T>, 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<T>::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<T>::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 T>
- class IdentifierList : public std::list<T>, 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<T>::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<Rational> 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<T>::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<T>::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 <root-name> - 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) )
{