*/
#include <AS_DCP.h>
+#include <list>
#ifndef _AS_DCP_SUBTITLE_H_
//
namespace TimedText
{
+ enum MIMEType_t { MT_BIN, MT_PNG, MT_OPENTYPE };
+
+ struct TimedTextResourceDescriptor
+ {
+ byte_t ResourceID[UUIDlen];
+ MIMEType_t Type;
+
+ TimedTextResourceDescriptor() : Type(MT_BIN) {}
+ };
+
+ typedef std::list<TimedTextResourceDescriptor> ResourceList_t;
+
struct TimedTextDescriptor
{
- std::string NamespaceName;
- ui32_t ResourceCount;
+ Rational EditRate; //
+ ui32_t ContainerDuration;
+ byte_t AssetID[UUIDlen];
+ std::string NamespaceName; // NULL-terminated string
+ std::string EncodingName;
+ ResourceList_t ResourceList;
+
+ TimedTextDescriptor() : ContainerDuration(0), EncodingName("UTF-8") {} // D-Cinema format is always UTF-8
};
// Print debugging information to stream (stderr default)
//
class FrameBuffer : public ASDCP::FrameBuffer
- {
- ASDCP_NO_COPY_CONSTRUCT(FrameBuffer); // TODO: should have copy construct
-
- protected:
- std::string m_MIMEType;
- byte_t m_AssetID[UUIDlen];
-
- public:
- FrameBuffer() { memset(m_AssetID, 0, UUIDlen); }
- FrameBuffer(ui32_t size) { Capacity(size); memset(m_AssetID, 0, UUIDlen); }
- virtual ~FrameBuffer() {}
-
- const char* MIMEType() { return m_MIMEType.c_str(); }
- void MIMEType(const char* s) { m_MIMEType = s; }
- const byte_t* AssetID() { return m_AssetID; }
- void AssetID(const byte_t* buf) { memcpy(m_AssetID, buf, UUIDlen); }
-
- // Print debugging information to stream (stderr default)
- void Dump(FILE* = 0, ui32_t dump_bytes = 0) const;
- };
+ {
+ ASDCP_NO_COPY_CONSTRUCT(FrameBuffer); // TODO: should have copy construct
+
+ protected:
+ byte_t m_AssetID[UUIDlen];
+ std::string m_MIMEType;
+
+ public:
+ FrameBuffer() { memset(m_AssetID, 0, UUIDlen); }
+ FrameBuffer(ui32_t size) { Capacity(size); memset(m_AssetID, 0, UUIDlen); }
+ virtual ~FrameBuffer() {}
+
+ inline const byte_t* AssetID() const { return m_AssetID; }
+ inline void AssetID(const byte_t* buf) { memcpy(m_AssetID, buf, UUIDlen); }
+ inline const char* MIMEType() const { return m_MIMEType.c_str(); }
+ inline void MIMEType(const std::string& s) { m_MIMEType = s; }
+
+ // Print debugging information to stream (stderr default)
+ void Dump(FILE* = 0, ui32_t dump_bytes = 0) const;
+ };
//
- // NOTE: The ReadFrame() and WriteFrame() methods below do not stricly handle "frames".
- // They are named for continuity with other AS-DCP lib modules. The methods actually
- // handle complete assets, such as XML documents, PNG images and fonts.
- //
-
- // An object which opens and reads a SMPTE 428-7 (or T.I. CineCanvas (TM)) subtitle file.
- // The call to OpenRead() reads metadata from the file and populates an internal TimedTextDescriptor
- // object. The first call to ReadFrame() returns the XML document. Each subsequent call to
- // ReadFrame() reads exactly one resource file (if any) referenced by the XML into the given
- // FrameBuffer object.
class DCSubtitleParser
{
- class h__DCSubtitleParser;
- mem_ptr<h__DCSubtitleParser> m_Parser;
+ class h__SubtitleParser;
+ mem_ptr<h__SubtitleParser> m_Parser;
ASDCP_NO_COPY_CONSTRUCT(DCSubtitleParser);
public:
DCSubtitleParser();
virtual ~DCSubtitleParser();
- // Opens the XML file for reading, parses enough data to provide a complete
+ // Opens the XML file for reading, parse data to provide a complete
// set of stream metadata for the MXFWriter below.
Result_t OpenRead(const char* filename) const;
// Returns RESULT_INIT if the file is not open.
Result_t FillDescriptor(TimedTextDescriptor&) const;
- // Reset the contents of the internal TimedTextDescriptor
- Result_t Reset() const;
+ // Reads the complete Timed Text Resource into the given string.
+ Result_t ReadTimedTextResource(std::string&) const;
- // Reads the next subtitle resource in the list taken from the XML file.
- // Fails if the buffer is too small or the file list has been exhausted.
- // The XML file itself is returned in the first call.
- Result_t ReadFrame(FrameBuffer&) const;
+ // Reads the Ancillary Resource having the given ID. Fails if the buffer
+ // is too small or the resource does not exist.
+ Result_t ReadAncillaryResource(const byte_t* uuid, FrameBuffer&) const;
};
-
//
class MXFWriter
{
Result_t OpenWrite(const char* filename, const WriterInfo&,
const TimedTextDescriptor&, ui32_t HeaderSize = 16384);
- // Writes a timed-text resource to the MXF file. If the optional AESEncContext
+ // Writes the Timed-Text Resource to the MXF file. The file must be UTF-8
+ // encoded. If the optional AESEncContext argument is present, the essence
+ // is encrypted prior to writing. Fails if the file is not open, is finalized,
+ // or an operating system error occurs.
+ // This method may only be called once, and it must be called before any
+ // call to WriteAncillaryResource(). RESULT_STATE will be returned if these
+ // conditions are not met.
+ Result_t WriteTimedTextResource(const std::string& XMLDoc, AESEncContext* = 0, HMACContext* = 0);
+
+ // Writes an Ancillary Resource to the MXF file. If the optional AESEncContext
// argument is present, the essence is encrypted prior to writing.
// Fails if the file is not open, is finalized, or an operating system
- // error occurs.
- Result_t WriteFrame(const FrameBuffer&, AESEncContext* = 0, HMACContext* = 0);
+ // error occurs. RESULT_STATE will be returned if the method is called before
+ // WriteTimedTextResource()
+ Result_t WriteAncillaryResource(const FrameBuffer&, AESEncContext* = 0, HMACContext* = 0);
// Closes the MXF file, writing the index and revised header.
Result_t Finalize();
// Returns RESULT_INIT if the file is not open.
Result_t FillWriterInfo(WriterInfo&) const;
- // Reads a timed-text resource from the MXF file. If the optional AESEncContext
+ // Reads the complete Timed Text Resource into the given string. Fails if the resource
+ // is encrypted and AESDecContext is NULL (use the following method to retrieve the
+ // raw ciphertet block).
+ Result_t ReadTimedTextResource(std::string&, AESDecContext* = 0, HMACContext* = 0) const;
+
+ // Reads the complete Timed Text Resource from the MXF file. If the optional AESEncContext
// argument is present, the resource is decrypted after reading. If the MXF
// file is encrypted and the AESDecContext argument is NULL, the frame buffer
// will contain the ciphertext frame data. If the HMACContext argument is
// not NULL, the HMAC will be calculated (if the file supports it).
// Returns RESULT_INIT if the file is not open, failure if the frame number is
// out of range, or if optional decrypt or HAMC operations fail.
- Result_t ReadFrame(ui32_t frame_number, FrameBuffer&, AESDecContext* = 0, HMACContext* = 0) const;
+ Result_t ReadTimedTextResource(FrameBuffer&, AESDecContext* = 0, HMACContext* = 0) const;
+
+ // Reads the timed-text resource having the given UUID from the MXF file. If the
+ // optional AESEncContext argument is present, the resource is decrypted after
+ // reading. If the MXF file is encrypted and the AESDecContext argument is NULL,
+ // the frame buffer will contain the ciphertext frame data. If the HMACContext
+ // argument is not NULL, the HMAC will be calculated (if the file supports it).
+ // Returns RESULT_INIT if the file is not open, failure if the frame number is
+ // out of range, or if optional decrypt or HAMC operations fail.
+ Result_t ReadAncillaryResource(const byte_t* uuid, FrameBuffer&, AESDecContext* = 0, HMACContext* = 0) const;
// Print debugging information to stream
void DumpHeaderMetadata(FILE* = 0) const;
// 1.0.1. If changes were also required in AS_DCP.h, the new version would be 1.1.1.
const ui32_t VERSION_MAJOR = 1;
const ui32_t VERSION_APIMINOR = 1;
- const ui32_t VERSION_IMPMINOR = 14;
+ const ui32_t VERSION_IMPMINOR = 15;
const char* Version();
// UUIDs are passed around as strings of UUIDlen bytes
ESS_JPEG_2000, // the file contains one or more JPEG 2000 codestreams
ESS_PCM_24b_48k, // the file contains one or more PCM audio pairs
ESS_PCM_24b_96k, // the file contains one or more PCM audio pairs
+ ESS_TIMED_TEXT, // the file contains an XML timed text document and one or more resources
};
// Determine the type of essence contained in the given MXF file. RESULT_OK
h__Reader() : m_EssenceDescriptor(0), m_EssenceSubDescriptor(0) {}
Result_t OpenRead(const char*);
Result_t ReadFrame(ui32_t, FrameBuffer&, AESDecContext*, HMACContext*);
- Result_t ReadFrameGOPStart(ui32_t, FrameBuffer&, AESDecContext*, HMACContext*);
Result_t MD_to_JP2K_PDesc(JP2K::PictureDescriptor& PDesc);
};
if ( ! m_File.IsOpen() )
return RESULT_INIT;
- return ReadEKLVPacket(FrameNum, FrameBuf, Dict::ul(MDD_JPEG2000Essence), Ctx, HMAC);
+ return ReadEKLVFrame(FrameNum, FrameBuf, Dict::ul(MDD_JPEG2000Essence), Ctx, HMAC);
}
//------------------------------------------------------------------------------------------
if ( ! m_File.IsOpen() )
return RESULT_INIT;
- Result_t result = ReadEKLVPacket(FrameNum, FrameBuf, Dict::ul(MDD_MPEG2Essence), Ctx, HMAC);
+ Result_t result = ReadEKLVFrame(FrameNum, FrameBuf, Dict::ul(MDD_MPEG2Essence), Ctx, HMAC);
if ( ASDCP_FAILURE(result) )
return result;
/*
-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
*/
#include <KM_fileio.h>
+#include <KM_xml.h>
#include "AS_DCP_internal.h"
#include "JP2K.h"
#include "MPEG.h"
{
if ( ASDCP_SUCCESS(TestHeader.GetMDObjectByType(OBJ_TYPE_ARGS(MPEG2VideoDescriptor))) )
type = ESS_MPEG2_VES;
+ else
+ {
+ if ( ASDCP_SUCCESS(TestHeader.GetMDObjectByType(OBJ_TYPE_ARGS(DCTimedTextDescriptor))) )
+ type = ESS_TIMED_TEXT;
+ }
}
}
}
Kumu::FileReader Reader;
ASDCP::Wav::SimpleWaveHeader WavHeader;
ASDCP::AIFF::SimpleAIFFHeader AIFFHeader;
+ Kumu::XMLElement TmpElement("Tmp");
+
ui32_t data_offset;
ui32_t read_count;
Result_t result = FB.Capacity(Wav::MaxWavHeader); // using Wav max because everything else is much smaller
if ( ASDCP_SUCCESS(result) )
{
const byte_t* p = FB.RoData();
+ FB.Size(read_count);
+
ui32_t i = 0;
while ( p[i] == 0 ) i++;
if ( i > 1 && p[i] == 1 && (p[i+1] == ASDCP::MPEG2::SEQ_START || p[i+1] == ASDCP::MPEG2::PIC_START) )
type = ESS_MPEG2_VES;
+ else if ( TmpElement.TestString((const char*)p, FB.Size()) )
+ type = ESS_TIMED_TEXT;
+
else if ( ASDCP_SUCCESS(WavHeader.ReadFromBuffer(p, read_count, &data_offset)) )
type = ESS_PCM_24b_48k;
if ( ! m_File.IsOpen() )
return RESULT_INIT;
- return ReadEKLVPacket(FrameNum, FrameBuf, Dict::ul(MDD_WAVEssence), Ctx, HMAC);
+ return ReadEKLVFrame(FrameNum, FrameBuf, Dict::ul(MDD_WAVEssence), Ctx, HMAC);
}
//------------------------------------------------------------------------------------------
#include "AS_DCP_TimedText.h"
#include "KM_xml.h"
-using namespace Kumu;
-using namespace ASDCP;
+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_DEF_LABEL = "Timed Text Track";
//------------------------------------------------------------------------------------------
+const char*
+MIME2str(TimedText::MIMEType_t m)
+{
+ if ( m == TimedText::MT_PNG )
+ return "image/png";
+
+ else if ( m == TimedText::MT_OPENTYPE )
+ return "application/x-opentype";
+
+ return "application/octet-stream";
+}
+
+//
+void
+ASDCP::TimedText::DescriptorDump(ASDCP::TimedText::TimedTextDescriptor const& TDesc, FILE* stream)
+{
+ if ( stream == 0 )
+ stream = stderr;
+
+ UUID TmpID(TDesc.AssetID);
+ char buf[64];
+
+ 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());
+
+ TimedText::ResourceList_t::const_iterator ri;
+ for ( ri = TDesc.ResourceList.begin() ; ri != TDesc.ResourceList.end(); ri++ )
+ {
+ TmpID.Set((*ri).ResourceID);
+ fprintf(stream, " %s: %s\n",
+ TmpID.EncodeHex(buf, 64),
+ MIME2str((*ri).Type));
+ }
+}
+
//
void
ASDCP::TimedText::FrameBuffer::Dump(FILE* stream, ui32_t dump_len) const
UUID TmpID(m_AssetID);
char buf[64];
- fprintf(stream, "ID: %s (type %s)\n", TmpID.EncodeHex(buf, 64), m_MIMEType.c_str());
+ fprintf(stream, "%s | %s | %u\n", TmpID.EncodeHex(buf, 64), m_MIMEType.c_str(), Size());
if ( dump_len > 0 )
Kumu::hexdump(m_Data, dump_len, stream);
//------------------------------------------------------------------------------------------
+typedef std::map<UUID, UUID> ResourceMap_t;
+
class ASDCP::TimedText::MXFReader::h__Reader : public ASDCP::h__Reader
{
- TimedTextDescriptor* m_EssenceDescriptor;
+ TimedTextDescriptor* m_EssenceDescriptor;
+ ResourceMap_t m_ResourceMap;
ASDCP_NO_COPY_CONSTRUCT(h__Reader);
public:
TimedTextDescriptor m_TDesc;
- h__Reader() : m_EssenceDescriptor(0) {}
+ h__Reader() : m_EssenceDescriptor(0) {
+ memset(&m_TDesc.AssetID, 0, UUIDlen);
+ }
+
Result_t OpenRead(const char*);
- Result_t ReadFrame(ui32_t, FrameBuffer&, AESDecContext*, HMACContext*);
- Result_t ReadFrameGOPStart(ui32_t, FrameBuffer&, AESDecContext*, HMACContext*);
- Result_t MD_to_TimedText_PDesc(TimedText::TimedTextDescriptor& TDesc);
+ Result_t MD_to_TimedText_TDesc(TimedText::TimedTextDescriptor& TDesc);
+ Result_t ReadTimedTextResource(FrameBuffer& FrameBuf, AESDecContext* Ctx, HMACContext* HMAC);
+ Result_t ReadAncillaryResource(const byte_t*, FrameBuffer& FrameBuf, AESDecContext* Ctx, HMACContext* HMAC);
};
+//
+ASDCP::Result_t
+ASDCP::TimedText::MXFReader::h__Reader::MD_to_TimedText_TDesc(TimedText::TimedTextDescriptor& TDesc)
+{
+ assert(m_EssenceDescriptor);
+ memset(&m_TDesc.AssetID, 0, UUIDlen);
+ MXF::DCTimedTextDescriptor* TDescObj = (MXF::DCTimedTextDescriptor*)m_EssenceDescriptor;
+
+ TDesc.EditRate = TDescObj->SampleRate;
+ TDesc.ContainerDuration = TDescObj->ContainerDuration;
+ TDesc.NamespaceName = TDescObj->RootNamespaceName;
+ TDesc.EncodingName = TDescObj->UTFEncoding;
+
+ Batch<UUID>::const_iterator sdi = TDescObj->SubDescriptors.begin();
+ DCTimedTextResourceDescriptor* DescObject = 0;
+ Result_t result = RESULT_OK;
+
+ for ( ; sdi != TDescObj->SubDescriptors.end() && KM_SUCCESS(result); sdi++ )
+ {
+ result = m_HeaderPart.GetMDObjectByID(*sdi, (InterchangeObject**)&DescObject);
+
+ if ( KM_SUCCESS(result) )
+ {
+ TimedTextResourceDescriptor TmpResource;
+ memcpy(TmpResource.ResourceID, DescObject->ResourcePackageID.Value(), UUIDlen);
+
+ if ( DescObject->ResourceMIMEType.find("font/") != std::string::npos )
+ TmpResource.Type = MT_OPENTYPE;
+
+ else if ( DescObject->ResourceMIMEType.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->ResourcePackageID, *sdi));
+ }
+ else
+ {
+ DefaultLogSink().Error("Broken sub-descriptor link\n");
+ return RESULT_FORMAT;
+ }
+ }
+
+ return RESULT_OK;
+}
+
+//
+ASDCP::Result_t
+ASDCP::TimedText::MXFReader::h__Reader::OpenRead(char const* filename)
+{
+ Result_t result = OpenMXFRead(filename);
+
+ if( ASDCP_SUCCESS(result) )
+ {
+ if ( m_EssenceDescriptor == 0 )
+ m_HeaderPart.GetMDObjectByType(OBJ_TYPE_ARGS(DCTimedTextDescriptor), (InterchangeObject**)&m_EssenceDescriptor);
+
+ result = MD_to_TimedText_TDesc(m_TDesc);
+ }
+
+ if( ASDCP_SUCCESS(result) )
+ result = InitMXFIndex();
+
+ if( ASDCP_SUCCESS(result) )
+ result = InitInfo();
+
+ return result;
+}
+
+//
+ASDCP::Result_t
+ASDCP::TimedText::MXFReader::h__Reader::ReadTimedTextResource(FrameBuffer& FrameBuf,
+ AESDecContext* Ctx, HMACContext* HMAC)
+{
+ if ( ! m_File.IsOpen() )
+ return RESULT_INIT;
+
+ return ReadEKLVFrame(0, FrameBuf, Dict::ul(MDD_DCTimedTextEssence), Ctx, HMAC);
+}
+
+//
+ASDCP::Result_t
+ASDCP::TimedText::MXFReader::h__Reader::ReadAncillaryResource(const byte_t* uuid, FrameBuffer& FrameBuf,
+ AESDecContext* Ctx, HMACContext* HMAC)
+{
+ KM_TEST_NULL_L(uuid);
+ UUID RID(uuid);
+
+ ResourceMap_t::const_iterator ri = m_ResourceMap.find(RID);
+ if ( ri == m_ResourceMap.end() )
+ {
+ char buf[64];
+ DefaultLogSink().Error("No such resource: %s\n", RID.EncodeHex(buf, 64));
+ return RESULT_FORMAT;
+ }
+
+ DCTimedTextResourceDescriptor* DescObject = 0;
+ // get the subdescriptor
+ Result_t result = m_HeaderPart.GetMDObjectByID((*ri).second, (InterchangeObject**)&DescObject);
+
+ if ( KM_SUCCESS(result) )
+ {
+ Array<RIP::Pair>::const_iterator pi;
+ RIP::Pair TmpPair;
+ ui32_t sequence = 1;
+
+ // look up the partition start in the RIP using the SID
+ // count the distance in because this is the sequence value needed to
+ // complete the HMAC
+ // result = m_HeaderPart.m_RIP.GetPairBySID(DescObject->ResourceSID, TmpPair);
+ for ( pi = m_HeaderPart.m_RIP.PairArray.begin(); pi != m_HeaderPart.m_RIP.PairArray.end(); pi++, sequence++ )
+ {
+ if ( (*pi).BodySID == DescObject->ResourceSID )
+ {
+ TmpPair = *pi;
+ break;
+ }
+ }
+
+ if ( TmpPair.ByteOffset == 0 )
+ {
+ DefaultLogSink().Error("Body SID not found in RIP set: %d\n", DescObject->ResourceSID);
+ return RESULT_FORMAT;
+ }
+
+ if ( KM_SUCCESS(result) )
+ {
+ FrameBuf.AssetID(uuid);
+ FrameBuf.MIMEType(DescObject->ResourceMIMEType);
+
+ // seek tp the start of the partition
+ if ( (Kumu::fpos_t)TmpPair.ByteOffset != m_LastPosition )
+ {
+ m_LastPosition = TmpPair.ByteOffset;
+ result = m_File.Seek(TmpPair.ByteOffset);
+ }
+
+ // read the partition header
+ MXF::Partition GSPart;
+ result = GSPart.InitFromFile(m_File);
+
+ if( ASDCP_SUCCESS(result) )
+ {
+ // check the SID
+ if ( DescObject->ResourceSID != GSPart.BodySID )
+ {
+ char buf[64];
+ DefaultLogSink().Error("Generic stream partition body differs: %s\n", RID.EncodeHex(buf, 64));
+ return RESULT_FORMAT;
+ }
+
+ // read the essence packet
+ if( ASDCP_SUCCESS(result) )
+ result = ReadEKLVPacket(0, FrameBuf, Dict::ul(MDD_DCTimedTextDescriptor), Ctx, HMAC);
+ }
+ }
+ }
+
+ return result;
+}
+
+
//------------------------------------------------------------------------------------------
ASDCP::TimedText::MXFReader::MXFReader()
return m_Reader->OpenRead(filename);
}
-//
-ASDCP::Result_t
-ASDCP::TimedText::MXFReader::ReadFrame(ui32_t FrameNum, FrameBuffer& FrameBuf,
- AESDecContext* Ctx, HMACContext* HMAC) const
-{
- if ( m_Reader && m_Reader->m_File.IsOpen() )
- return m_Reader->ReadFrame(FrameNum, FrameBuf, Ctx, HMAC);
-
- return RESULT_INIT;
-}
-
-
// Fill the struct with the values from the file's header.
// Returns RESULT_INIT if the file is not open.
ASDCP::Result_t
return RESULT_INIT;
}
-
// Fill the struct with the values from the file's header.
// Returns RESULT_INIT if the file is not open.
ASDCP::Result_t
return RESULT_INIT;
}
+//
+ASDCP::Result_t
+ASDCP::TimedText::MXFReader::ReadTimedTextResource(std::string& s, AESDecContext* Ctx, HMACContext* HMAC) const
+{
+ FrameBuffer FrameBuf(2*Kumu::Megabyte);
+
+ Result_t result = ReadTimedTextResource(FrameBuf, Ctx, HMAC);
+
+ if ( ASDCP_SUCCESS(result) )
+ s.assign((char*)FrameBuf.Data(), FrameBuf.Size());
+
+ return result;
+}
+
+//
+ASDCP::Result_t
+ASDCP::TimedText::MXFReader::ReadTimedTextResource(FrameBuffer& FrameBuf,
+ AESDecContext* Ctx, HMACContext* HMAC) const
+{
+ if ( m_Reader && m_Reader->m_File.IsOpen() )
+ return m_Reader->ReadTimedTextResource(FrameBuf, Ctx, HMAC);
+
+ return RESULT_INIT;
+}
+
+//
+ASDCP::Result_t
+ASDCP::TimedText::MXFReader::ReadAncillaryResource(const byte_t* uuid, FrameBuffer& FrameBuf,
+ AESDecContext* Ctx, HMACContext* HMAC) const
+{
+ if ( m_Reader && m_Reader->m_File.IsOpen() )
+ return m_Reader->ReadAncillaryResource(uuid, FrameBuf, Ctx, HMAC);
+
+ return RESULT_INIT;
+}
+
+
//
void
ASDCP::TimedText::MXFReader::DumpHeaderMetadata(FILE* stream) const
public:
TimedTextDescriptor m_TDesc;
byte_t m_EssenceUL[SMPTE_UL_LENGTH];
+ ui32_t m_ResourceSID;
ASDCP_NO_COPY_CONSTRUCT(h__Writer);
- h__Writer() {
+ h__Writer() : m_ResourceSID(10) {
memset(m_EssenceUL, 0, SMPTE_UL_LENGTH);
}
Result_t OpenWrite(const char*, ui32_t HeaderSize);
Result_t SetSourceStream(const TimedTextDescriptor&);
- Result_t WriteFrame(const FrameBuffer&, AESEncContext* = 0, HMACContext* = 0);
+ Result_t WriteTimedTextResource(const std::string& XMLDoc, AESEncContext* = 0, HMACContext* = 0);
+ Result_t WriteAncillaryResource(const FrameBuffer&, AESEncContext* = 0, HMACContext* = 0);
Result_t Finalize();
- Result_t TimedText_PDesc_to_MD(TimedText::TimedTextDescriptor& PDesc);
+ Result_t TimedText_TDesc_to_MD(TimedText::TimedTextDescriptor& TDesc);
};
+//
+ASDCP::Result_t
+ASDCP::TimedText::MXFWriter::h__Writer::TimedText_TDesc_to_MD(TimedText::TimedTextDescriptor& TDesc)
+{
+ assert(m_EssenceDescriptor);
+ // assert(m_EssenceSubDescriptor);
+ MXF::DCTimedTextDescriptor* TDescObj = (MXF::DCTimedTextDescriptor*)m_EssenceDescriptor;
+
+ TDescObj->SampleRate = TDesc.EditRate;
+ TDescObj->ContainerDuration = TDesc.ContainerDuration;
+ TDescObj->RootNamespaceName = TDesc.NamespaceName;
+ TDescObj->UTFEncoding = TDesc.EncodingName;
+
+ return RESULT_OK;
+}
+
+//
+ASDCP::Result_t
+ASDCP::TimedText::MXFWriter::h__Writer::OpenWrite(char const* filename, ui32_t HeaderSize)
+{
+ if ( ! m_State.Test_BEGIN() )
+ return RESULT_STATE;
+
+ Result_t result = m_File.OpenWrite(filename);
+
+ if ( ASDCP_SUCCESS(result) )
+ {
+ m_HeaderSize = HeaderSize;
+ m_EssenceDescriptor = new DCTimedTextDescriptor();
+ result = m_State.Goto_INIT();
+ }
+
+ return result;
+}
+
+//
+ASDCP::Result_t
+ASDCP::TimedText::MXFWriter::h__Writer::SetSourceStream(ASDCP::TimedText::TimedTextDescriptor const& TDesc)
+{
+ if ( ! m_State.Test_INIT() )
+ return RESULT_STATE;
+
+ m_TDesc = TDesc;
+ ResourceList_t::const_iterator ri;
+ Result_t result = TimedText_TDesc_to_MD(m_TDesc);
+
+ for ( ri = m_TDesc.ResourceList.begin() ; ri != m_TDesc.ResourceList.end() && ASDCP_SUCCESS(result); ri++ )
+ {
+ DCTimedTextResourceDescriptor* resourceSubdescriptor = new DCTimedTextResourceDescriptor;
+ GenRandomValue(resourceSubdescriptor->InstanceUID);
+ resourceSubdescriptor->ResourcePackageID.Set((*ri).ResourceID);
+ resourceSubdescriptor->ResourceMIMEType = MIME2str((*ri).Type);
+ resourceSubdescriptor->ResourceSID = m_ResourceSID++;
+ m_EssenceSubDescriptorList.push_back((FileDescriptor*)resourceSubdescriptor);
+ m_EssenceDescriptor->SubDescriptors.push_back(resourceSubdescriptor->InstanceUID);
+ }
+
+ m_ResourceSID = 10;
+
+ if ( ASDCP_SUCCESS(result) )
+ {
+ InitHeader();
+ AddDMSegment(m_TDesc.EditRate, 24, TIMED_TEXT_DEF_LABEL,
+ UL(Dict::ul(MDD_PictureDataDef)), TIMED_TEXT_PACKAGE_LABEL);
+
+ AddEssenceDescriptor(UL(Dict::ul(MDD_DCTimedTextWrapping)));
+
+ result = m_HeaderPart.WriteToFile(m_File, m_HeaderSize);
+
+ if ( KM_SUCCESS(result) )
+ result = CreateBodyPart(m_TDesc.EditRate);
+ }
+
+ if ( ASDCP_SUCCESS(result) )
+ {
+ memcpy(m_EssenceUL, Dict::ul(MDD_DCTimedTextEssence), SMPTE_UL_LENGTH);
+ m_EssenceUL[SMPTE_UL_LENGTH-1] = 1; // first (and only) essence container
+ result = m_State.Goto_READY();
+ }
+
+ return result;
+}
+
+//
+ASDCP::Result_t
+ASDCP::TimedText::MXFWriter::h__Writer::WriteTimedTextResource(const std::string& XMLDoc,
+ ASDCP::AESEncContext* Ctx, ASDCP::HMACContext* HMAC)
+{
+ Result_t result = m_State.Goto_RUNNING();
+
+ if ( ASDCP_SUCCESS(result) )
+ {
+ // TODO: make sure it's XML
+
+ ui32_t str_size = XMLDoc.size();
+ FrameBuffer FrameBuf(str_size);
+
+ memcpy(FrameBuf.Data(), XMLDoc.c_str(), str_size);
+ FrameBuf.Size(str_size);
+
+ IndexTableSegment::IndexEntry Entry;
+ Entry.StreamOffset = m_StreamOffset;
+
+ if ( ASDCP_SUCCESS(result) )
+ result = WriteEKLVPacket(FrameBuf, m_EssenceUL, Ctx, HMAC);
+
+ if ( ASDCP_SUCCESS(result) )
+ {
+ m_FooterPart.PushIndexEntry(Entry);
+ m_FramesWritten++;
+ }
+ }
+
+ return result;
+}
+
+
+//
+ASDCP::Result_t
+ASDCP::TimedText::MXFWriter::h__Writer::WriteAncillaryResource(const ASDCP::TimedText::FrameBuffer& FrameBuf,
+ ASDCP::AESEncContext* Ctx, ASDCP::HMACContext* HMAC)
+{
+ if ( ! m_State.Test_RUNNING() )
+ return RESULT_STATE;
+
+ Kumu::fpos_t here = m_File.Tell();
+
+ // create generic stream partition header
+ MXF::Partition GSPart;
+
+ GSPart.ThisPartition = here;
+ GSPart.PreviousPartition = m_HeaderPart.m_RIP.PairArray.back().ByteOffset;
+ GSPart.BodySID = m_ResourceSID;
+ 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)));
+ UL TmpUL(Dict::ul(MDD_GenericStreamPartition));
+ Result_t result = GSPart.WriteToFile(m_File, TmpUL);
+
+ if ( ASDCP_SUCCESS(result) )
+ result = WriteEKLVPacket(FrameBuf, m_EssenceUL, Ctx, HMAC);
+
+ m_FramesWritten++;
+ return result;
+}
+
+//
+ASDCP::Result_t
+ASDCP::TimedText::MXFWriter::h__Writer::Finalize()
+{
+ if ( ! m_State.Test_RUNNING() )
+ return RESULT_STATE;
+
+ m_FramesWritten = m_TDesc.ContainerDuration;
+ m_State.Goto_FINAL();
+
+ return WriteMXFFooter();
+}
+
//------------------------------------------------------------------------------------------
ASDCP::TimedText::MXFWriter::OpenWrite(const char* filename, const WriterInfo& Info,
const TimedTextDescriptor& TDesc, ui32_t HeaderSize)
{
+ if ( Info.LabelSetType != LS_MXF_SMPTE )
+ {
+ DefaultLogSink().Error("Timed Text support requires LS_MXF_SMPTE\n");
+ return RESULT_FORMAT;
+ }
+
m_Writer = new h__Writer;
Result_t result = m_Writer->OpenWrite(filename, HeaderSize);
return result;
}
+//
+ASDCP::Result_t
+ASDCP::TimedText::MXFWriter::WriteTimedTextResource(const std::string& XMLDoc, AESEncContext* Ctx, HMACContext* HMAC)
+{
+ if ( m_Writer.empty() )
+ return RESULT_INIT;
-// Writes a frame of essence to the MXF file. If the optional AESEncContext
-// argument is present, the essence is encrypted prior to writing.
-// Fails if the file is not open, is finalized, or an operating system
-// error occurs.
+ return m_Writer->WriteTimedTextResource(XMLDoc, Ctx, HMAC);
+}
+
+//
ASDCP::Result_t
-ASDCP::TimedText::MXFWriter::WriteFrame(const FrameBuffer& FrameBuf, AESEncContext* Ctx, HMACContext* HMAC)
+ASDCP::TimedText::MXFWriter::WriteAncillaryResource(const FrameBuffer& FrameBuf, AESEncContext* Ctx, HMACContext* HMAC)
{
if ( m_Writer.empty() )
return RESULT_INIT;
- return m_Writer->WriteFrame(FrameBuf, Ctx, HMAC);
+ return m_Writer->WriteAncillaryResource(FrameBuf, Ctx, HMAC);
}
// Closes the MXF file, writing the index and other closing information.
Result_t InitInfo();
Result_t OpenMXFRead(const char* filename);
Result_t InitMXFIndex();
+
+ // positions file before reading
+ Result_t ReadEKLVFrame(ui32_t FrameNum, ASDCP::FrameBuffer& FrameBuf,
+ const byte_t* EssenceUL, AESDecContext* Ctx, HMACContext* HMAC);
+
+ // reads from current position
Result_t ReadEKLVPacket(ui32_t FrameNum, ASDCP::FrameBuffer& FrameBuf,
const byte_t* EssenceUL, AESDecContext* Ctx, HMACContext* HMAC);
void Close();
inline Result_t Goto_FINAL() { Goto_body(ST_RUNNING, ST_FINAL); }
};
+ typedef std::list<ui64_t*> DurationElementList_t;
+
//
class h__Writer
{
ui64_t m_EssenceStart;
MaterialPackage* m_MaterialPackage;
- Sequence* m_MPTCSequence;
- TimecodeComponent* m_MPTimecode;
- Sequence* m_MPClSequence;
- SourceClip* m_MPClip; //! Material Package SourceClip for each essence stream
-
SourcePackage* m_FilePackage;
- Sequence* m_FPTCSequence;
- TimecodeComponent* m_FPTimecode;
- Sequence* m_FPClSequence;
- SourceClip* m_FPClip; //! File Package SourceClip for each essence stream
FileDescriptor* m_EssenceDescriptor;
std::list<FileDescriptor*> m_EssenceSubDescriptorList;
ASDCP::FrameBuffer m_CtFrameBuf;
h__WriterState m_State;
WriterInfo m_Info;
+ DurationElementList_t m_DurationUpdateList;
h__Writer();
virtual ~h__Writer();
+ void InitHeader();
+ void AddSourceClip(const MXF::Rational& EditRate, ui32_t TCFrameRate,
+ const std::string& TrackName, const UL& DataDefinition,
+ const std::string& PackageLabel);
+ void AddDMSegment(const MXF::Rational& EditRate, ui32_t TCFrameRate,
+ const std::string& TrackName, const UL& DataDefinition,
+ const std::string& PackageLabel);
+ void AddEssenceDescriptor(const UL& WrappingUL);
+ Result_t CreateBodyPart(const MXF::Rational& EditRate, ui32_t BytesPerEditUnit = 0);
+
+ // all the above for a single source clip
Result_t WriteMXFHeader(const std::string& PackageLabel, const UL& WrappingUL,
const std::string& TrackName, const UL& DataDefinition,
const MXF::Rational& EditRate,
}
else
{
- fprintf(stream, " IndexEntryArray: %u entries\n", IndexEntryArray.size());
+ fprintf(stream, " IndexEntryArray: %lu entries\n", IndexEntryArray.size());
}
}
/*
-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
typedef struct stat fstat_t;
#endif
+static void
+split(const std::string& str, char separator, std::list<std::string>& components)
+{
+ const char* pstr = str.c_str();
+ const char* r = strchr(pstr, separator);
+
+ while( r != NULL )
+ {
+ char* cp = new char[(r-pstr)+1];
+ memcpy(cp, pstr, (r-pstr));
+ cp[(r-pstr)] = '\0';
+
+ if( strlen(cp) > 0 )
+ {
+ std::string s(cp);
+ components.push_back(s);
+ }
+
+ delete[] cp;
+ pstr = r + 1;
+ r = strchr(pstr, separator);
+ }
+
+ if( strlen(pstr) > 0 )
+ components.push_back(std::string(pstr));
+}
+
//
static Kumu::Result_t
do_stat(const char* path, fstat_t* stat_info)
//
bool
-Kumu::PathIsFile(const char* pathname)
+Kumu::PathExists(const std::string& pathname)
+{
+ if ( pathname.empty() )
+ return false;
+
+ fstat_t info;
+
+ if ( KM_SUCCESS(do_stat(pathname.c_str(), &info)) )
+ return true;
+
+ return false;
+}
+
+//
+bool
+Kumu::PathIsFile(const std::string& pathname)
{
- if ( pathname == 0 || *pathname == 0 )
+ if ( pathname.empty() )
return false;
fstat_t info;
- if ( KM_SUCCESS(do_stat(pathname, &info)) )
+ if ( KM_SUCCESS(do_stat(pathname.c_str(), &info)) )
{
if ( info.st_mode & ( S_IFREG|S_IFLNK ) )
return true;
//
bool
-Kumu::PathIsDirectory(const char* pathname)
+Kumu::PathIsDirectory(const std::string& pathname)
{
- if ( pathname == 0 || *pathname == 0 )
+ if ( pathname.empty() )
return false;
fstat_t info;
- if ( KM_SUCCESS(do_stat(pathname, &info)) )
+ if ( KM_SUCCESS(do_stat(pathname.c_str(), &info)) )
{
if ( info.st_mode & S_IFDIR )
return true;
return false;
}
-
//
Kumu::fsize_t
-Kumu::FileSize(const char* pathname)
+Kumu::FileSize(const std::string& pathname)
{
- if ( pathname == 0 || *pathname == 0 )
- return false;
+ if ( pathname.empty() )
+ return 0;
fstat_t info;
- if ( KM_SUCCESS(do_stat(pathname, &info)) )
+ if ( KM_SUCCESS(do_stat(pathname.c_str(), &info)) )
{
if ( info.st_mode & ( S_IFREG|S_IFLNK ) )
return(info.st_size);
return 0;
}
+//
+static PathCompList_t&
+s_PathMakeCanonical(PathCompList_t& CList, char separator, bool is_absolute)
+{
+ PathCompList_t::iterator ci, ri; // component and removal iterators
+
+ for ( ci = CList.begin(); ci != CList.end(); ci++ )
+ {
+ if ( *ci == "." && ( CList.size() > 1 || is_absolute ) )
+ {
+ ri = ci++;
+ CList.erase(ri);
+ }
+ else if ( *ci == ".." && ci != CList.begin() )
+ {
+ ri = ci;
+ ri--;
+
+ if ( *ri != ".." )
+ {
+ CList.erase(ri);
+ ri = ci++;
+ CList.erase(ri);
+ }
+ }
+ }
+
+ return CList;
+}
+
+//
+std::string
+Kumu::PathMakeCanonical(const std::string& Path, char separator)
+{
+ PathCompList_t CList;
+ bool is_absolute = PathIsAbsolute(Path, separator);
+ s_PathMakeCanonical(PathToComponents(Path, CList, separator), separator, is_absolute);
+
+ if ( is_absolute )
+ return ComponentsToAbsolutePath(CList, separator);
+
+ return ComponentsToPath(CList, separator);
+}
+
+//
+bool
+Kumu::PathsAreEquivalent(const std::string& lhs, const std::string& rhs)
+{
+ return PathMakeCanonical(lhs) == PathMakeCanonical(rhs);
+}
+
+//
+Kumu::PathCompList_t&
+Kumu::PathToComponents(const std::string& Path, PathCompList_t& CList, char separator)
+{
+ split(Path, separator, CList);
+ return CList;
+}
+
+//
+std::string
+Kumu::ComponentsToPath(const PathCompList_t& CList, char separator)
+{
+ if ( CList.empty() )
+ return "";
+
+ PathCompList_t::const_iterator ci = CList.begin();
+ std::string out_path = *ci;
+
+ for ( ci++; ci != CList.end(); ci++ )
+ out_path += separator + *ci;
+
+ return out_path;
+}
+
+//
+std::string
+Kumu::ComponentsToAbsolutePath(const PathCompList_t& CList, char separator)
+{
+ std::string out_path;
+
+ if ( CList.empty() )
+ out_path = separator;
+ else
+ {
+ PathCompList_t::const_iterator ci;
+
+ for ( ci = CList.begin(); ci != CList.end(); ci++ )
+ out_path += separator + *ci;
+ }
+
+ return out_path;
+}
+
+//
+bool
+Kumu::PathHasComponents(const std::string& Path, char separator)
+{
+ if ( strchr(Path.c_str(), separator) == 0 )
+ return false;
+
+ return true;
+}
+
+//
+bool
+Kumu::PathIsAbsolute(const std::string& Path, char separator)
+{
+ if ( Path.empty() )
+ return false;
+
+ if ( Path[0] == separator)
+ return true;
+
+ return false;
+}
+
+//
+std::string
+Kumu::PathMakeAbsolute(const std::string& Path, char separator)
+{
+ if ( Path.empty() )
+ {
+ std::string out_path;
+ out_path = separator;
+ return out_path;
+ }
+
+ if ( PathIsAbsolute(Path, separator) )
+ return Path;
+
+ char cwd_buf [MaxFilePath];
+ if ( getcwd(cwd_buf, MaxFilePath) == 0 )
+ {
+ DefaultLogSink().Error("Error retrieving current working directory.");
+ return "";
+ }
+
+ PathCompList_t CList;
+ CList.push_back(cwd_buf);
+ CList.push_back(Path);
+
+ return ComponentsToAbsolutePath(s_PathMakeCanonical(CList, separator, true), separator);
+}
+
+//
+std::string
+Kumu::PathMakeLocal(const std::string& Path, const std::string& Parent)
+{
+ size_t pos = Path.find(Parent);
+
+ if ( pos == 0 ) // Parent found at offset 0
+ return Path.substr(Parent.size()+1);
+
+ return Path;
+}
+
+//
+std::string
+Kumu::PathBasename(const std::string& Path, char separator)
+{
+ PathCompList_t CList;
+ PathToComponents(Path, CList, separator);
+
+ if ( CList.empty() )
+ return "";
+
+ return CList.back();
+}
+
+//
+std::string
+Kumu::PathDirname(const std::string& Path, char separator)
+{
+ PathCompList_t CList;
+ bool is_absolute = PathIsAbsolute(Path, separator);
+ PathToComponents(Path, CList, separator);
+
+ if ( CList.empty() )
+ return is_absolute ? "/" : "";
+
+ CList.pop_back();
+
+ if ( is_absolute )
+ return ComponentsToAbsolutePath(CList, separator);
+
+ return ComponentsToPath(CList, separator);
+}
+
+//
+std::string
+Kumu::PathGetExtension(const std::string& Path)
+{
+ std::string Basename = PathBasename(Path);
+ const char* p = strrchr(Basename.c_str(), '.');
+
+ if ( p++ == 0 )
+ return "";
+
+ return p;
+}
+
+//
+std::string
+Kumu::PathSetExtension(const std::string& Path, const std::string& Extension) // empty extension removes
+{
+ std::string Basename = PathBasename(Path);
+ const char* p = strrchr(Basename.c_str(), '.');
+
+ if ( p != 0 )
+ Basename = Basename.substr(0, p - Basename.c_str());
+
+ if ( Extension.empty() )
+ return Basename;
+
+ return Basename + "." + Extension;
+}
+
+//
+Kumu::PathList_t&
+Kumu::FindInPaths(const IPathMatch& Pattern, const Kumu::PathList_t& SearchPaths,
+ Kumu::PathList_t& FoundPaths, bool one_shot, char separator)
+{
+ PathList_t::const_iterator si;
+ for ( si = SearchPaths.begin(); si != SearchPaths.end(); si++ )
+ {
+ FindInPath(Pattern, *si, FoundPaths, one_shot, separator);
+
+ if ( one_shot && ! FoundPaths.empty() )
+ break;
+ }
+
+ return FoundPaths;
+}
+
+//
+Kumu::PathList_t&
+Kumu::FindInPath(const IPathMatch& Pattern, const std::string& SearchDir,
+ Kumu::PathList_t& FoundPaths, bool one_shot, char separator)
+{
+ char name_buf[MaxFilePath];
+ DirScanner Dir;
+
+ if ( KM_SUCCESS(Dir.Open(SearchDir.c_str())) )
+ {
+ while ( KM_SUCCESS(Dir.GetNext(name_buf)) )
+ {
+ if ( name_buf[0] == '.' ) continue; // no hidden files
+ std::string tmp_path = SearchDir + separator + name_buf;
+
+ if ( PathIsDirectory(tmp_path.c_str()) )
+ FindInPath(Pattern, tmp_path, FoundPaths, one_shot, separator);
+
+ else if ( Pattern.Match(name_buf) )
+ {
+ FoundPaths.push_back(SearchDir + separator + name_buf);
+ if ( one_shot )
+ break;
+ }
+ }
+ }
+
+ return FoundPaths;
+}
+
+
+#ifndef KM_WIN32
+
+//
+Kumu::PathMatchRegex::PathMatchRegex(const std::string& s)
+{
+ int result = regcomp(&m_regex, s.c_str(), REG_NOSUB); // (REG_EXTENDED|REG_NOSUB|REG_NEWLINE));
+
+ if ( result )
+ {
+ char buf[128];
+ regerror(result, &m_regex, buf, 128);
+ DefaultLogSink().Error("PathMatchRegex: %s\n", buf);
+ regfree(&m_regex);
+ }
+}
+
+Kumu::PathMatchRegex::PathMatchRegex(const PathMatchRegex& rhs) {
+ m_regex = rhs.m_regex;
+}
+
+Kumu::PathMatchRegex::~PathMatchRegex() {
+ regfree(&m_regex);
+}
+
+bool
+Kumu::PathMatchRegex::Match(const std::string& s) const {
+ return ( regexec(&m_regex, s.c_str(), 0, 0, 0) == 0 );
+}
+
+
+
+//
+Kumu::PathMatchGlob::PathMatchGlob(const std::string& glob)
+{
+ std::string regex; // convert glob to regex
+
+ for ( const char* p = glob.c_str(); *p != 0; p++ )
+ {
+ switch (*p)
+ {
+ case '.': regex += "\\."; break;
+ case '*': regex += ".*"; break;
+ case '?': regex += ".?"; break;
+ default: regex += *p;
+ }
+ }
+ regex += '$';
+
+ int result = regcomp(&m_regex, regex.c_str(), REG_NOSUB);
+
+ if ( result )
+ {
+ char buf[128];
+ regerror(result, &m_regex, buf, 128);
+ DefaultLogSink().Error("PathMatchRegex: %s\n", buf);
+ regfree(&m_regex);
+ }
+}
+
+Kumu::PathMatchGlob::PathMatchGlob(const PathMatchGlob& rhs) {
+ m_regex = rhs.m_regex;
+}
+
+Kumu::PathMatchGlob::~PathMatchGlob() {
+ regfree(&m_regex);
+}
+
+bool
+Kumu::PathMatchGlob::Match(const std::string& s) const {
+ return ( regexec(&m_regex, s.c_str(), 0, 0, 0) == 0 );
+}
+
+#endif
+
//------------------------------------------------------------------------------------------
// portable aspects of the file classes
BOOL result = ::WriteFile(m_Handle, buf, buf_len, (DWORD*)bytes_written, NULL);
::SetErrorMode(prev);
- if ( result == 0 || bytes_written != buf_len )
+ if ( result == 0 || *bytes_written != buf_len )
return Kumu::RESULT_WRITEFAIL;
return Kumu::RESULT_OK;
# include <unistd.h>
# include <time.h>
# include <sys/types.h>
+#include <regex.h>
#endif
#include <sys/stat.h>
namespace Kumu
{
-#ifdef KM_WIN32
//
class DirScanner
{
public:
+#ifdef KM_WIN32
__int64 m_Handle;
struct _finddatai64_t m_FileInfo;
+#else
+ DIR* m_Handle;
+#endif
DirScanner() {};
~DirScanner() { Close(); }
+
Result_t Open(const char*);
Result_t Close();
Result_t GetNext(char*);
};
-#else // KM_WIN32
- // POSIX directory scanner
- //
- class DirScanner
- {
- public:
- DIR* m_Handle;
-
- DirScanner() : m_Handle(NULL) {}
- ~DirScanner() { Close(); }
-
- Result_t Open(const char*);
- Result_t Close();
- Result_t GetNext(char*);
- };
-#endif // KM_WIN32
#ifdef KM_WIN32
typedef __int64 fsize_t;
const ui32_t MaxFilePath = Kilobyte;
- bool PathIsFile(const char* pathname);
- bool PathIsDirectory(const char* pathname);
- fsize_t FileSize(const char* pathname);
+ // Path Manglers
+ //
+ typedef std::list<std::string> PathCompList_t; // a list of path components
+ typedef std::list<std::string> PathList_t; // a list of paths
+
+ bool PathExists(const std::string& Path); // true if the path exists in the filesystem
+ bool PathIsFile(const std::string& Path); // true if the path exists in the filesystem and is a file
+ bool PathIsDirectory(const std::string& Path); // true if the path exists in the filesystem and is a directory
+ fsize_t FileSize(const std::string& Path); // returns the size of a regular file, 0 for a directory or device
+ bool PathsAreEquivalent(const std::string& lhs, const std::string& rhs); // true if paths point to the same filesystem entry
+
+ // split and reassemble pats as lists of path components
+ PathCompList_t& PathToComponents(const std::string& Path, PathCompList_t& CList, char separator = '/'); // removes '//'
+ std::string ComponentsToPath(const PathCompList_t& CList, char separator = '/');
+ std::string ComponentsToAbsolutePath(const PathCompList_t& CList, char separator = '/'); // add separator to the front
+ bool PathHasComponents(const std::string& Path, char separator = '/'); // true if paths starts with separator
+
+ bool PathIsAbsolute(const std::string& Path, char separator = '/'); // true if path begins with separator
+ std::string PathMakeAbsolute(const std::string& Path, char separator = '/'); // compute position of relative path using getcwd()
+ std::string PathMakeLocal(const std::string& Path, const std::string& Parent); // remove Parent from front of Path, if it exists
+ std::string PathMakeCanonical(const std::string& Path, char separator = '/'); // remove '.' and '..'
+
+ std::string PathBasename(const std::string& Path, char separator = '/'); // returns right-most path element (list back())
+ std::string PathDirname(const std::string& Path, char separator = '/'); // returns everything but the right-most element
+ std::string PathGetExtension(const std::string& Path); // returns everything in the right-most element following the right-most '.'
+ std::string PathSetExtension(const std::string& Path, const std::string& Extension); // empty extension removes '.' as well
+ //
+ //
+ class IPathMatch
+ {
+ public:
+ virtual ~IPathMatch() {}
+ virtual bool Match(const std::string& s) const = 0;
+ };
+
+ class PathMatchAny : public IPathMatch
+ {
+ public:
+ virtual ~PathMatchAny() {}
+ inline bool Match(const std::string& s) const { return true; }
+ };
+
+ class PathMatchRegex : public IPathMatch
+ {
+ regex_t m_regex;
+ PathMatchRegex();
+ const PathMatchRegex& operator=(const PathMatchRegex&);
+
+ public:
+ PathMatchRegex(const std::string& Pattern);
+ PathMatchRegex(const PathMatchRegex&);
+ virtual ~PathMatchRegex();
+ bool Match(const std::string& s) const;
+ };
+
+ class PathMatchGlob : public IPathMatch
+ {
+ regex_t m_regex;
+ PathMatchGlob();
+ const PathMatchGlob& operator=(const PathMatchGlob&);
+
+ public:
+ PathMatchGlob(const std::string& Pattern);
+ PathMatchGlob(const PathMatchGlob&);
+ virtual ~PathMatchGlob();
+ bool Match(const std::string& s) const;
+ };
+
+ // Search all paths in SearchPaths for filenames matching Pattern (no directories are returned).
+ // Put results in FoundPaths. Returns after first find if one_shot is true.
+ PathList_t& FindInPath(const IPathMatch& Pattern, const std::string& SearchDir,
+ PathList_t& FoundPaths, bool one_shot, char separator);
+
+ PathList_t& FindInPaths(const IPathMatch& Pattern, const PathList_t& SearchPaths,
+ PathList_t& FoundPaths, bool one_shot = false, char separator = '/');
+
+
+ // Instant IO for strings
+ //
// Reads an entire file into a string.
Result_t ReadFileIntoString(const char* filename, std::string& outString, ui32_t max_size = 8 * Megabyte);
*/
#include <KM_xml.h>
+#include <KM_log.h>
+#include <stack>
+#include <map>
+#ifdef ASDCP_USE_EXPAT
+#include <expat.h>
+#endif
+using namespace Kumu;
-Kumu::XMLElement::XMLElement(const char* name)
+
+class ns_map : public std::map<std::string, XMLNamespace*>
+{
+public:
+ ns_map() {}
+ ~ns_map()
+ {
+ ns_map::iterator ni = begin();
+
+ while (ni != end() )
+ {
+ // fprintf(stderr, "deleting namespace %s:%s\n", ni->second->Prefix().c_str(), ni->second->Name().c_str());
+ delete ni->second;
+ ni++;
+ }
+ }
+};
+
+
+Kumu::XMLElement::XMLElement(const char* name) : m_Namespace(0), m_NamespaceOwner(0)
{
m_Name = name;
}
{
for ( Elem_i i = m_ChildList.begin(); i != m_ChildList.end(); i++ )
delete *i;
+
+ if ( m_NamespaceOwner != 0 )
+ delete (ns_map*)m_NamespaceOwner;
}
//
return AddChildWithContent(name, value.c_str());
}
+//
+void
+Kumu::XMLElement::AppendBody(const std::string& value)
+{
+ m_Body += value;
+}
+
//
Kumu::XMLElement*
Kumu::XMLElement::AddChildWithContent(const char* name, const char* value)
//
void
-Kumu::XMLElement::Render(std::string& outbuf)
+Kumu::XMLElement::Render(std::string& outbuf) const
{
outbuf = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
RenderElement(outbuf, 0);
//
void
-Kumu::XMLElement::RenderElement(std::string& outbuf, ui32_t depth)
+Kumu::XMLElement::RenderElement(std::string& outbuf, ui32_t depth) const
{
add_spacer(outbuf, depth);
outbuf += ">\n";
}
+//
+bool
+Kumu::XMLElement::HasName(const char* name) const
+{
+ if ( name == 0 || *name == 0 )
+ return false;
+
+ return (m_Name == name);
+}
+
+
+void
+Kumu::XMLElement::SetName(const char* name)
+{
+ if ( name != 0)
+ m_Name = name;
+}
+
+//
+const char*
+Kumu::XMLElement::GetAttrWithName(const char* name) const
+{
+ for ( Attr_i i = m_AttrList.begin(); i != m_AttrList.end(); i++ )
+ {
+ if ( (*i).name == name )
+ return (*i).value.c_str();
+ }
+
+ return 0;
+}
+
+//
+Kumu::XMLElement*
+Kumu::XMLElement::GetChildWithName(const char* name) const
+{
+ for ( Elem_i i = m_ChildList.begin(); i != m_ChildList.end(); i++ )
+ {
+ if ( (*i)->HasName(name) )
+ return *i;
+ }
+
+ return 0;
+}
+
+//
+const Kumu::ElementList&
+Kumu::XMLElement::GetChildrenWithName(const char* name, ElementList& outList) const
+{
+ assert(name);
+ for ( Elem_i i = m_ChildList.begin(); i != m_ChildList.end(); i++ )
+ {
+ if ( (*i)->HasName(name) )
+ outList.push_back(*i);
+
+ if ( ! (*i)->m_ChildList.empty() )
+ (*i)->GetChildrenWithName(name, outList);
+ }
+
+ return outList;
+}
+
+//----------------------------------------------------------------------------------------------------
+
+#ifdef ASDCP_USE_EXPAT
+
+
+class ExpatParseContext
+{
+ KM_NO_COPY_CONSTRUCT(ExpatParseContext);
+ ExpatParseContext();
+public:
+ ns_map* Namespaces;
+ std::stack<XMLElement*> Scope;
+ XMLElement* Root;
+
+ ExpatParseContext(XMLElement* root) : Root(root) {
+ Namespaces = new ns_map;
+ assert(Root);
+ }
+
+ ~ExpatParseContext() {}
+};
+
+// expat wrapper functions
+//
+static void
+xph_start(void* p, const XML_Char* name, const XML_Char** attrs)
+{
+ assert(p); assert(name); assert(attrs);
+ ExpatParseContext* Ctx = (ExpatParseContext*)p;
+ XMLElement* Element;
+
+ const char* ns_root = name;
+ const char* local_name = strchr(name, '|');
+ if ( local_name != 0 )
+ name = local_name + 1;
+
+ if ( Ctx->Scope.empty() )
+ {
+ Ctx->Scope.push(Ctx->Root);
+ }
+ else
+ {
+ Element = Ctx->Scope.top();
+ Ctx->Scope.push(Element->AddChild(name));
+ }
+
+ Element = Ctx->Scope.top();
+ Element->SetName(name);
+
+ // map the namespace
+ std::string key;
+ if ( ns_root != name )
+ key.assign(ns_root, name - ns_root - 1);
+
+ ns_map::iterator ni = Ctx->Namespaces->find(key);
+ if ( ni != Ctx->Namespaces->end() )
+ Element->SetNamespace(ni->second);
+
+ // set attributes
+ for ( int i = 0; attrs[i] != 0; i += 2 )
+ {
+ if ( ( local_name = strchr(attrs[i], '|') ) == 0 )
+ local_name = attrs[i];
+ else
+ local_name++;
+
+ Element->SetAttr(local_name, attrs[i+1]);
+ }
+}
+
+//
+static void
+xph_end(void* p, const XML_Char* name)
+{
+ assert(p); assert(name);
+ ExpatParseContext* Ctx = (ExpatParseContext*)p;
+ Ctx->Scope.pop();
+}
+
+//
+static void
+xph_char(void* p, const XML_Char* data, int len)
+{
+ assert(p); assert(data);
+ ExpatParseContext* Ctx = (ExpatParseContext*)p;
+
+ if ( len > 0 )
+ {
+ std::string tmp_str;
+ tmp_str.assign(data, len);
+ Ctx->Scope.top()->AppendBody(tmp_str);
+ }
+}
+
+//
+void
+xph_namespace_start(void* p, const XML_Char* ns_prefix, const XML_Char* ns_name)
+{
+ assert(p); assert(ns_name);
+ ExpatParseContext* Ctx = (ExpatParseContext*)p;
+
+ if ( ns_prefix == 0 )
+ ns_prefix = "";
+
+ ns_map::iterator ni = Ctx->Namespaces->find(ns_name);
+
+ if ( ni != Ctx->Namespaces->end() )
+ {
+ if ( ni->second->Name() != std::string(ns_name) )
+ {
+ DefaultLogSink().Error("Duplicate prefix: %s\n", ns_prefix);
+ return;
+ }
+ }
+ else
+ {
+ XMLNamespace* Namespace = new XMLNamespace(ns_prefix, ns_name);
+ Ctx->Namespaces->insert(ns_map::value_type(ns_name, Namespace));
+ }
+}
+
+//
+bool
+Kumu::XMLElement::ParseString(const std::string& document)
+{
+ XML_Parser Parser = XML_ParserCreateNS("UTF-8", '|');
+
+ if ( Parser == 0 )
+ {
+ DefaultLogSink().Error("Error allocating memory for XML parser.\n");
+ return false;
+ }
+
+ ExpatParseContext Ctx(this);
+ XML_SetUserData(Parser, (void*)&Ctx);
+ XML_SetElementHandler(Parser, xph_start, xph_end);
+ XML_SetCharacterDataHandler(Parser, xph_char);
+ XML_SetStartNamespaceDeclHandler(Parser, xph_namespace_start);
+
+ if ( ! XML_Parse(Parser, document.c_str(), document.size(), 1) )
+ {
+ XML_ParserFree(Parser);
+ DefaultLogSink().Error("XML Parse error on line %d: %s\n",
+ XML_GetCurrentLineNumber(Parser),
+ XML_ErrorString(XML_GetErrorCode(Parser)));
+ return false;
+ }
+
+ XML_ParserFree(Parser);
+
+ if ( ! Ctx.Namespaces->empty() )
+ m_NamespaceOwner = (void*)Ctx.Namespaces;
+
+ return true;
+}
+
+//------------------------------------------------------------------------------------------
+
+struct xph_test_wrapper
+{
+ XML_Parser Parser;
+ bool Status;
+
+ xph_test_wrapper(XML_Parser p) : Parser(p), Status(false) {}
+};
+
+// expat wrapper functions, map callbacks to IASAXHandler
+//
+static void
+xph_test_start(void* p, const XML_Char* name, const XML_Char** attrs)
+{
+ assert(p);
+ xph_test_wrapper* Wrapper = (xph_test_wrapper*)p;
+
+ Wrapper->Status = true;
+ XML_StopParser(Wrapper->Parser, false);
+}
+
+
+//
+bool
+Kumu::XMLElement::TestString(const char* document, ui32_t len)
+{
+ if ( document == 0 )
+ return false;
+
+ if ( len == 0 )
+ len = strlen(document);
+
+ XML_Parser Parser = XML_ParserCreate("UTF-8");
+
+ if ( Parser == 0 )
+ {
+ DefaultLogSink().Error("Error allocating memory for XML parser.\n");
+ return false;
+ }
+
+ xph_test_wrapper Wrapper(Parser);
+ XML_SetUserData(Parser, (void*)&Wrapper);
+ XML_SetStartElementHandler(Parser, xph_test_start);
+
+ XML_Parse(Parser, document, len, 1);
+ XML_ParserFree(Parser);
+ return Wrapper.Status;
+}
+
+#else // no XML parser support
+
+//
+bool
+Kumu::XMLElement::ParseString(const std::string& document)
+{
+ DefaultLogSink().Error("asdcplib compiled without XML parser support.\n");
+ return false;
+}
+
+//
+bool
+Kumu::XMLElement::TestString(const char* document, ui32_t len)
+{
+ DefaultLogSink().Error("asdcplib compiled without XML parser support.\n");
+ return false;
+}
+
+#endif
+
//
// end KM_xml.cpp
{
class XMLElement;
+ //
struct NVPair
{
std::string name;
std::string value;
};
+ //
typedef std::list<NVPair> AttributeList;
- typedef AttributeList::iterator Attr_i;
+ typedef AttributeList::const_iterator Attr_i;
typedef std::list<XMLElement*> ElementList;
- typedef ElementList::iterator Elem_i;
+ typedef ElementList::const_iterator Elem_i;
+
+ //
+ class XMLNamespace
+ {
+ std::string m_Prefix;
+ std::string m_Name;
+
+ KM_NO_COPY_CONSTRUCT(XMLNamespace);
+ XMLNamespace();
+
+ public:
+ XMLNamespace(const char* prefix, const char* name) : m_Prefix(prefix), m_Name(name) {}
+ ~XMLNamespace() {}
+
+ inline const std::string& Prefix() const { return m_Prefix; }
+ inline const std::string& Name() const { return m_Name; }
+ };
//
class XMLElement
{
- AttributeList m_AttrList;
- ElementList m_ChildList;
+ AttributeList m_AttrList;
+ ElementList m_ChildList;
+ const XMLNamespace* m_Namespace;
+ void* m_NamespaceOwner;
+
+ std::string m_Name;
+ std::string m_Body;
KM_NO_COPY_CONSTRUCT(XMLElement);
XMLElement();
public:
- std::string m_Name;
- std::string m_Body;
-
XMLElement(const char* name);
~XMLElement();
+ inline const XMLNamespace* Namespace() const { return m_Namespace; }
+ inline void SetNamespace(const XMLNamespace* ns) { assert(ns); m_Namespace = ns; }
+
+ bool ParseString(const std::string& document);
+ bool TestString(const char* document, ui32_t len = 0);
+
+ // building
+ void SetName(const char* name);
+ void AppendBody(const std::string& value);
void SetAttr(const char* name, const char* value);
XMLElement* AddChild(const char* name);
XMLElement* AddChildWithContent(const char* name, const char* value);
XMLElement* AddChildWithContent(const char* name, const std::string& value);
XMLElement* AddChildWithPrefixedContent(const char* name, const char* prefix, const char* value);
void AddComment(const char* value);
- void Render(std::string&);
- void RenderElement(std::string& outbuf, ui32_t depth);
+ void Render(std::string&) const;
+ void RenderElement(std::string& outbuf, ui32_t depth) const;
+
+ // querying
+ inline const std::string& GetBody() const { return m_Body; }
+ const char* GetAttrWithName(const char* name) const;
+ XMLElement* GetChildWithName(const char* name) const;
+ const ElementList& GetChildrenWithName(const char* name, ElementList& outList) const;
+ bool HasName(const char* name) const;
+
};
} // namespace Kumu
{ { 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_UTFEncoding" },
+ { { 0x06, 0x0e, 0x2b, 0x34, 0x00, 0x01, 0x01, 0x01, // 259
+ 0x0d, 0x01, 0x03, 0x01, 0xfa, 0xce, 0x00, 0x04 },
+ {0}, false, "DCTimedTextDescriptor_RootNamespaceName" },
+ { { 0x06, 0x0e, 0x2b, 0x34, 0x00, 0x01, 0x01, 0x01, // 260
+ 0x0d, 0x01, 0x03, 0x01, 0xfa, 0xce, 0x00, 0x05 },
+ {0}, false, "DCTimedTextResourceDescriptor" },
+ { { 0x06, 0x0e, 0x2b, 0x34, 0x00, 0x01, 0x01, 0x01, // 261
+ 0x0d, 0x01, 0x03, 0x01, 0xfa, 0xce, 0x00, 0x06 },
+ {0}, false, "DCTimedTextResourceDescriptor_ResourcePackageID" },
+ { { 0x06, 0x0e, 0x2b, 0x34, 0x00, 0x01, 0x01, 0x01, // 262
+ 0x0d, 0x01, 0x03, 0x01, 0xfa, 0xce, 0x00, 0x07 },
+ {0}, false, "DCTimedTextResourceDescriptor_ResourceMIMEType" },
+ { { 0x06, 0x0e, 0x2b, 0x34, 0x00, 0x01, 0x01, 0x01, // 263
+ 0x0d, 0x01, 0x03, 0x01, 0xfa, 0xce, 0x00, 0x08 },
+ {0}, false, "DCTimedTextResourceDescriptor_ResourceSID" },
+ { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, // 264
+ 0x06, 0x10, 0x10, 0x05, 0x01, 0x02, 0x11, 0x00 },
+ {0}, false, "GenericStreamPartition" },
+ { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02, // 265
+ 0x04, 0x07, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ {0x02, 0x01}, false, "DMSegment_DataDefinition" },
+ { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02, // 266
+ 0x07, 0x02, 0x02, 0x01, 0x01, 0x03, 0x00, 0x00 },
+ {0x02, 0x02}, true, "DMSegment_Duration" },
+ { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02, // 267
+ 0x01, 0x07, 0x01, 0x05, 0x00, 0x00, 0x00, 0x00 },
+ {0x61, 0x02}, false, "DMSegment_TrackIDList" },
{ {0}, {0}, false, 0 }
};
-const ui32_t s_MDD_Table_size = 255;
+const ui32_t s_MDD_Table_size = 268;
//
// end MDD.cpp
MDD_CryptographicContext_CipherAlgorithm, // 252
MDD_CryptographicContext_MICAlgorithm, // 253
MDD_CryptographicContext_CryptographicKeyID, // 254
+ MDD_DCTimedTextWrapping, // 255
+ MDD_DCTimedTextEssence, // 256
+ MDD_DCTimedTextDescriptor, // 257
+ MDD_DCTimedTextDescriptor_UTFEncoding, // 258
+ MDD_DCTimedTextDescriptor_RootNamespaceName, // 259
+ MDD_DCTimedTextResourceDescriptor, // 260
+ MDD_DCTimedTextResourceDescriptor_ResourcePackageID, // 261
+ MDD_DCTimedTextResourceDescriptor_ResourceMIMEType, // 262
+ MDD_DCTimedTextResourceDescriptor_ResourceSID, //263
+ MDD_GenericStreamPartition, // 264
+ MDD_DMSegment_DataDefinition, // 265
+ MDD_DMSegment_Duration, // 266
+ MDD_DMSegment_TrackIDList, // 267
}; // enum MDD_t
} // namespaceASDCP
*/
#include "MXF.h"
+#include "Metadata.h"
#include <KM_log.h>
using Kumu::DefaultLogSink;
return result;
}
+//
+ASDCP::Result_t
+ASDCP::MXF::RIP::GetPairBySID(ui32_t SID, Pair& outPair) const
+{
+ Array<Pair>::const_iterator pi = PairArray.begin();
+ for ( ; pi != PairArray.end(); pi++ )
+ {
+ if ( (*pi).BodySID == SID )
+ {
+ outPair = *pi;
+ return RESULT_OK;
+ }
+ }
+
+ return RESULT_FAIL;
+}
+
//
ASDCP::Result_t
ASDCP::MXF::RIP::InitFromFile(const Kumu::FileReader& Reader)
m_List.push_back(ThePacket);
}
+ //
+ Result_t GetMDObjectByID(const UUID& ObjectID, InterchangeObject** Object)
+ {
+ ASDCP_TEST_NULL(Object);
+
+ std::map<UUID, InterchangeObject*>::iterator mi = m_Map.find(ObjectID);
+
+ if ( mi == m_Map.end() )
+ {
+ *Object = 0;
+ return RESULT_FAIL;
+ }
+
+ *Object = (*mi).second;
+ return RESULT_OK;
+ }
+
//
Result_t GetMDObjectByType(const byte_t* ObjectID, InterchangeObject** Object)
{
return RESULT_FAIL;
}
+
+ //
+ Result_t GetMDObjectsByType(const byte_t* ObjectID, std::list<InterchangeObject*>& ObjectList)
+ {
+ ASDCP_TEST_NULL(ObjectID);
+ std::list<InterchangeObject*>::iterator li;
+
+ for ( li = m_List.begin(); li != m_List.end(); li++ )
+ {
+ if ( (*li)->HasUL(ObjectID) )
+ ObjectList.push_back(*li);
+ }
+
+ return ObjectList.empty() ? RESULT_FAIL : RESULT_OK;
+ }
};
//------------------------------------------------------------------------------------------
KLVPacket::Dump(stream, false);
fprintf(stream, "Primer: %u %s\n",
- LocalTagEntryBatch.size(),
+ (ui32_t)LocalTagEntryBatch.size(),
( LocalTagEntryBatch.size() == 1 ? "entry" : "entries" ));
Batch<LocalTagEntry>::iterator i = LocalTagEntryBatch.begin();
DefaultLogSink().Error("RIP contains no Pairs.\n");
result = RESULT_FORMAT;
}
- else if ( test_s < 2 || test_s > 3 )
- {
- // OP-Atom states that there will be either two or three partitions,
- // one closed header and one closed footer with an optional body
- DefaultLogSink().Error("RIP count is not 2 or 3: %u\n", test_s);
- return RESULT_FORMAT;
- }
else
{
+ if ( test_s < 2 || test_s > 3 )
+ {
+ // OP-Atom states that there will be either two or three partitions:
+ // one closed header and one closed footer with an optional body
+ DefaultLogSink().Warn("RIP count is not 2 or 3: %u\n", test_s);
+ }
+
m_HasRIP = true;
if ( m_RIP.PairArray.front().ByteOffset != 0 )
return result;
}
+ASDCP::Result_t
+ASDCP::MXF::OPAtomHeader::GetMDObjectByID(const UUID& ObjectID, InterchangeObject** Object)
+{
+ return m_PacketList->GetMDObjectByID(ObjectID, Object);
+}
+
//
ASDCP::Result_t
ASDCP::MXF::OPAtomHeader::GetMDObjectByType(const byte_t* ObjectID, InterchangeObject** Object)
return m_PacketList->GetMDObjectByType(ObjectID, Object);
}
+//
+ASDCP::Result_t
+ASDCP::MXF::OPAtomHeader::GetMDObjectsByType(const byte_t* ObjectID, std::list<InterchangeObject*>& ObjectList)
+{
+ return m_PacketList->GetMDObjectsByType(ObjectID, ObjectList);
+}
+
//
ASDCP::MXF::Identification*
ASDCP::MXF::OPAtomHeader::GetIdentification()
if ( ASDCP_SUCCESS(result) )
{
- ui32_t write_count;
- Writer.Write(FooterBuffer.RoData(), FooterBuffer.Size(), &write_count);
+ ui32_t write_count = 0;
+ result = Writer.Write(FooterBuffer.RoData(), FooterBuffer.Size(), &write_count);
assert(write_count == FooterBuffer.Size());
}
}
+//------------------------------------------------------------------------------------------
+
+
+typedef std::map<ASDCP::UL, ASDCP::MXF::MXFObjectFactory_t>FactoryMap_t;
+typedef FactoryMap_t::iterator FLi_t;
+
+//
+class FactoryList : public FactoryMap_t
+{
+ Kumu::Mutex m_Lock;
+
+public:
+ FactoryList() {}
+ ~FactoryList() {}
+
+ bool Empty() {
+ Kumu::AutoMutex BlockLock(m_Lock);
+ return empty();
+ }
+
+ FLi_t Find(const byte_t* label) {
+ Kumu::AutoMutex BlockLock(m_Lock);
+ return find(label);
+ }
+
+ FLi_t End() {
+ Kumu::AutoMutex BlockLock(m_Lock);
+ return end();
+ }
+
+ void Insert(ASDCP::UL label, ASDCP::MXF::MXFObjectFactory_t factory) {
+ Kumu::AutoMutex BlockLock(m_Lock);
+ insert(FactoryList::value_type(label, factory));
+ }
+};
+
+//
+static FactoryList s_FactoryList;
+static Kumu::Mutex s_InitLock;
+static bool s_TypesInit = false;
+
+
+//
+void
+ASDCP::MXF::SetObjectFactory(ASDCP::UL label, ASDCP::MXF::MXFObjectFactory_t factory)
+{
+ s_FactoryList.Insert(label, factory);
+}
+
+
+//
+ASDCP::MXF::InterchangeObject*
+ASDCP::MXF::CreateObject(const byte_t* label)
+{
+ if ( label == 0 )
+ return 0;
+
+ if ( ! s_TypesInit )
+ {
+ Kumu::AutoMutex BlockLock(s_InitLock);
+
+ if ( ! s_TypesInit )
+ {
+ MXF::Metadata_InitTypes();
+ s_TypesInit = true;
+ }
+ }
+
+ FLi_t i = s_FactoryList.find(label);
+
+ if ( i == s_FactoryList.end() )
+ return new InterchangeObject;
+
+ return i->second();
+}
+
+
+
//
// end MXF.cpp
//
{
class InterchangeObject;
+ //
+ typedef ASDCP::MXF::InterchangeObject* (*MXFObjectFactory_t)();
+
+ //
+ void SetObjectFactory(UL label, MXFObjectFactory_t factory);
+
+ //
+ InterchangeObject* CreateObject(const byte_t* label);
+
+
// seek an open file handle to the start of the RIP KLV packet
Result_t SeekToRIP(const Kumu::FileReader&);
virtual ~RIP() {}
virtual Result_t InitFromFile(const Kumu::FileReader& Reader);
virtual Result_t WriteToFile(Kumu::FileWriter& Writer);
+ virtual Result_t GetPairBySID(ui32_t, Pair&) const;
virtual void Dump(FILE* = 0);
};
virtual void Dump(FILE* stream = 0);
};
- //
- InterchangeObject* CreateObject(const byte_t* label);
-
//
class Preface : public InterchangeObject
{
virtual Result_t InitFromFile(const Kumu::FileReader& Reader);
virtual Result_t WriteToFile(Kumu::FileWriter& Writer, ui32_t HeaderLength = 16384);
virtual void Dump(FILE* = 0);
+ virtual Result_t GetMDObjectByID(const UUID&, InterchangeObject** = 0);
virtual Result_t GetMDObjectByType(const byte_t*, InterchangeObject** = 0);
+ virtual Result_t GetMDObjectsByType(const byte_t* ObjectID, std::list<InterchangeObject*>& ObjectList);
Identification* GetIdentification();
SourcePackage* GetSourcePackage();
};
/*
-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
#include <KM_prng.h>
#include "MXFTypes.h"
#include <KM_log.h>
+
using Kumu::DefaultLogSink;
//------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------
//
+//
const ASDCP::MXF::UTF16String&
ASDCP::MXF::UTF16String::operator=(const char* sz)
{
if ( sz == 0 || *sz == 0 )
- {
- m_length = 0;
- *m_buffer = 0;
- }
+ clear();
+
else
- {
- ui32_t len = Kumu::xmin((ui32_t)strlen(sz), (IdentBufferLen - 1));
- m_length = len;
- memcpy(m_buffer, sz, m_length);
- m_buffer[m_length] = 0;
- }
+ this->assign(sz);
return *this;
}
+//
+const ASDCP::MXF::UTF16String&
+ASDCP::MXF::UTF16String::operator=(const std::string& str)
+{
+ this->assign(str);
+ return *this;
+}
+
+//
+const char*
+ASDCP::MXF::UTF16String::EncodeString(char* str_buf, ui32_t buf_len) const
+{
+ ui32_t write_len = Kumu::xmin(buf_len - 1, (ui32_t)size());
+ strncpy(str_buf, c_str(), write_len);
+ str_buf[write_len] = 0;
+ return str_buf;
+}
//
bool
ASDCP::MXF::UTF16String::Unarchive(Kumu::MemIOReader* Reader)
{
- const byte_t* p = Reader->CurrentData();
- m_length = Reader->Remainder();
- assert(m_length % 2 == 0);
- m_length /= 2;
- assert(IdentBufferLen >= m_length);
- ui32_t i = 0;
+ clear();
+ const ui16_t* p = (ui16_t*)Reader->CurrentData();
+ ui32_t length = Reader->Remainder() / 2;
+ char mb_buf[MB_LEN_MAX+1];
- for ( i = 0; i < m_length; i++ )
- m_buffer[i] = p[(i*2)+1];
+ for ( ui32_t i = 0; i < length; i++ )
+ {
+ int count = wctomb(mb_buf, KM_i16_BE(p[i]));
- m_buffer[i] = 0;
+ if ( count == -1 )
+ {
+ DefaultLogSink().Error("Unable to decode wide character 0x%04hx\n", p[i]);
+ return false;
+ }
- Reader->SkipOffset(m_length*2);
+ assert(count <= MB_LEN_MAX);
+ mb_buf[count] = 0;
+ this->append(mb_buf);
+ }
+
+ Reader->SkipOffset(length*2);
return true;
}
bool
ASDCP::MXF::UTF16String::Archive(Kumu::MemIOWriter* Writer) const
{
- byte_t* p = Writer->Data() + Writer->Length();
+ if ( size() > IdentBufferLen )
+ {
+ DefaultLogSink().Error("String length exceeds maximum %u bytes\n", IdentBufferLen);
+ return false;
+ }
+
+ const char* mbp = c_str();
+ wchar_t wcp;
+ ui32_t remainder = size();
+ ui32_t length = size();
ui32_t i = 0;
- memset(p, 0, (m_length*2)+2);
- for ( i = 0; i < m_length; i++ )
- p[(i*2)+1] = m_buffer[i];
+ while ( i < length )
+ {
+ int count = mbtowc(&wcp, mbp+i, remainder);
+
+ if ( count == -1 )
+ {
+ DefaultLogSink().Error("Error decoding multi-byte sequence starting at offset %u\n", i);
+ return false;
+ }
+ else if ( count == 0 )
+ break;
+
+ bool result = Writer->WriteUi16BE((ui16_t)wcp);
+
+ if ( result == false )
+ {
+ DefaultLogSink().Error("No more space in memory IO writer\n");
+ return false;
+ }
+
+ i += count;
+ remainder -= count;
+ }
- Writer->AddOffset(m_length * 2);
return true;
}
};
//
- class UTF16String : public Kumu::IArchive
+ class UTF16String : public std::string, public Kumu::IArchive
{
- ui16_t m_length;
- char m_buffer[IdentBufferLen];
- ASDCP_NO_COPY_CONSTRUCT(UTF16String);
-
public:
- UTF16String() : m_length(0) { *m_buffer = 0; }
+ UTF16String() {}
~UTF16String() {}
const UTF16String& operator=(const char*);
+ const UTF16String& operator=(const std::string&);
- //
- const char* EncodeString(char* str_buf, ui32_t buf_len) const {
- strncpy(str_buf, m_buffer, Kumu::xmin(buf_len, ((ui32_t)m_length+1)));
- str_buf[buf_len-1] = 0;
- return str_buf;
- }
-
+ const char* EncodeString(char* str_buf, ui32_t buf_len) const;
virtual bool Unarchive(Kumu::MemIOReader* Reader);
- inline virtual bool HasValue() const { return m_length > 0; }
+ inline virtual bool HasValue() const { return ! empty(); }
virtual bool Archive(Kumu::MemIOWriter* Writer) const;
};
/*
-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
#include <KM_mutex.h>
#include "Metadata.h"
+using namespace ASDCP;
+using namespace ASDCP::MXF;
+
const ui32_t kl_length = ASDCP::SMPTE_UL_LENGTH + ASDCP::MXF_BER_LENGTH;
//------------------------------------------------------------------------------------------
-//
-enum FLT_t
- {
- FLT_Preface,
- FLT_IndexTableSegment,
- FLT_Identification,
- FLT_ContentStorage,
- FLT_EssenceContainerData,
- FLT_MaterialPackage,
- FLT_SourcePackage,
- FLT_StaticTrack,
- FLT_Track,
- FLT_Sequence,
- FLT_SourceClip,
- FLT_TimecodeComponent,
- FLT_FileDescriptor,
- FLT_GenericSoundEssenceDescriptor,
- FLT_WaveAudioDescriptor,
- FLT_GenericPictureEssenceDescriptor,
- FLT_RGBAEssenceDescriptor,
- FLT_JPEG2000PictureSubDescriptor,
- FLT_CDCIEssenceDescriptor,
- FLT_MPEG2VideoDescriptor,
- FLT_DMSegment,
- FLT_CryptographicFramework,
- FLT_CryptographicContext,
- };
-
-//
-typedef std::map<ASDCP::UL, FLT_t>::iterator FLi_t;
-
-class FactoryList : public std::map<ASDCP::UL, FLT_t>
-{
- Kumu::Mutex m_Lock;
-
-public:
- FactoryList() {}
- ~FactoryList() {}
-
- bool Empty() {
- Kumu::AutoMutex BlockLock(m_Lock);
- return empty();
- }
-
- FLi_t Find(const byte_t* label) {
- Kumu::AutoMutex BlockLock(m_Lock);
- return find(label);
- }
-
- FLi_t End() {
- Kumu::AutoMutex BlockLock(m_Lock);
- return end();
- }
-
-};
-
-//
-static FactoryList s_FactoryList;
-
-//
-ASDCP::MXF::InterchangeObject*
-ASDCP::MXF::CreateObject(const byte_t* label)
-{
- if ( label == 0 )
- return 0;
-
- if ( s_FactoryList.empty() )
- {
- s_FactoryList.insert(FactoryList::value_type(Dict::ul(MDD_Preface), FLT_Preface));
- s_FactoryList.insert(FactoryList::value_type(Dict::ul(MDD_IndexTableSegment), FLT_IndexTableSegment));
- s_FactoryList.insert(FactoryList::value_type(Dict::ul(MDD_Identification), FLT_Identification));
- s_FactoryList.insert(FactoryList::value_type(Dict::ul(MDD_ContentStorage), FLT_ContentStorage));
- s_FactoryList.insert(FactoryList::value_type(Dict::ul(MDD_EssenceContainerData), FLT_EssenceContainerData));
- s_FactoryList.insert(FactoryList::value_type(Dict::ul(MDD_MaterialPackage), FLT_MaterialPackage));
- s_FactoryList.insert(FactoryList::value_type(Dict::ul(MDD_SourcePackage), FLT_SourcePackage));
- s_FactoryList.insert(FactoryList::value_type(Dict::ul(MDD_StaticTrack), FLT_StaticTrack));
- s_FactoryList.insert(FactoryList::value_type(Dict::ul(MDD_Track), FLT_Track));
- s_FactoryList.insert(FactoryList::value_type(Dict::ul(MDD_Sequence), FLT_Sequence));
- s_FactoryList.insert(FactoryList::value_type(Dict::ul(MDD_SourceClip), FLT_SourceClip));
- s_FactoryList.insert(FactoryList::value_type(Dict::ul(MDD_TimecodeComponent), FLT_TimecodeComponent));
- s_FactoryList.insert(FactoryList::value_type(Dict::ul(MDD_FileDescriptor), FLT_FileDescriptor));
- s_FactoryList.insert(FactoryList::value_type(Dict::ul(MDD_GenericSoundEssenceDescriptor), FLT_GenericSoundEssenceDescriptor));
- s_FactoryList.insert(FactoryList::value_type(Dict::ul(MDD_WaveAudioDescriptor), FLT_WaveAudioDescriptor));
- s_FactoryList.insert(FactoryList::value_type(Dict::ul(MDD_GenericPictureEssenceDescriptor), FLT_GenericPictureEssenceDescriptor));
- s_FactoryList.insert(FactoryList::value_type(Dict::ul(MDD_RGBAEssenceDescriptor), FLT_RGBAEssenceDescriptor));
- s_FactoryList.insert(FactoryList::value_type(Dict::ul(MDD_JPEG2000PictureSubDescriptor), FLT_JPEG2000PictureSubDescriptor));
- s_FactoryList.insert(FactoryList::value_type(Dict::ul(MDD_CDCIEssenceDescriptor), FLT_CDCIEssenceDescriptor));
- s_FactoryList.insert(FactoryList::value_type(Dict::ul(MDD_MPEG2VideoDescriptor), FLT_MPEG2VideoDescriptor));
- s_FactoryList.insert(FactoryList::value_type(Dict::ul(MDD_DMSegment), FLT_DMSegment));
- s_FactoryList.insert(FactoryList::value_type(Dict::ul(MDD_CryptographicFramework), FLT_CryptographicFramework));
- s_FactoryList.insert(FactoryList::value_type(Dict::ul(MDD_CryptographicContext), FLT_CryptographicContext));
- }
-
- FLi_t i = s_FactoryList.find(label);
-
- if ( i == s_FactoryList.end() )
- return new InterchangeObject;
-
- switch ( i->second )
- {
- case FLT_Preface: return new Preface;
- case FLT_IndexTableSegment: return new IndexTableSegment;
- case FLT_Identification: return new Identification;
- case FLT_ContentStorage: return new ContentStorage;
- case FLT_EssenceContainerData: return new EssenceContainerData;
- case FLT_MaterialPackage: return new MaterialPackage;
- case FLT_SourcePackage: return new SourcePackage;
- case FLT_StaticTrack: return new StaticTrack;
- case FLT_Track: return new Track;
- case FLT_Sequence: return new Sequence;
- case FLT_SourceClip: return new SourceClip;
- case FLT_TimecodeComponent: return new TimecodeComponent;
- case FLT_FileDescriptor: return new FileDescriptor;
- case FLT_GenericSoundEssenceDescriptor: return new GenericSoundEssenceDescriptor;
- case FLT_WaveAudioDescriptor: return new WaveAudioDescriptor;
- case FLT_GenericPictureEssenceDescriptor: return new GenericPictureEssenceDescriptor;
- case FLT_RGBAEssenceDescriptor: return new RGBAEssenceDescriptor;
- case FLT_JPEG2000PictureSubDescriptor: return new JPEG2000PictureSubDescriptor;
- case FLT_CDCIEssenceDescriptor: return new CDCIEssenceDescriptor;
- case FLT_MPEG2VideoDescriptor: return new MPEG2VideoDescriptor;
- case FLT_DMSegment: return new DMSegment;
- case FLT_CryptographicFramework: return new CryptographicFramework;
- case FLT_CryptographicContext: return new CryptographicContext;
- }
-
- return 0;
-}
+static InterchangeObject* Preface_Factory() { return new Preface; }
+static InterchangeObject* IndexTableSegment_Factory() { return new IndexTableSegment; }
+
+static InterchangeObject* Identification_Factory() { return new Identification; }
+static InterchangeObject* ContentStorage_Factory() { return new ContentStorage; }
+static InterchangeObject* EssenceContainerData_Factory() { return new EssenceContainerData; }
+static InterchangeObject* MaterialPackage_Factory() { return new MaterialPackage; }
+static InterchangeObject* SourcePackage_Factory() { return new SourcePackage; }
+static InterchangeObject* StaticTrack_Factory() { return new StaticTrack; }
+static InterchangeObject* Track_Factory() { return new Track; }
+static InterchangeObject* Sequence_Factory() { return new Sequence; }
+static InterchangeObject* SourceClip_Factory() { return new SourceClip; }
+static InterchangeObject* TimecodeComponent_Factory() { return new TimecodeComponent; }
+static InterchangeObject* FileDescriptor_Factory() { return new FileDescriptor; }
+static InterchangeObject* GenericSoundEssenceDescriptor_Factory() { return new GenericSoundEssenceDescriptor; }
+static InterchangeObject* WaveAudioDescriptor_Factory() { return new WaveAudioDescriptor; }
+static InterchangeObject* GenericPictureEssenceDescriptor_Factory() { return new GenericPictureEssenceDescriptor; }
+static InterchangeObject* RGBAEssenceDescriptor_Factory() { return new RGBAEssenceDescriptor; }
+static InterchangeObject* JPEG2000PictureSubDescriptor_Factory() { return new JPEG2000PictureSubDescriptor; }
+static InterchangeObject* CDCIEssenceDescriptor_Factory() { return new CDCIEssenceDescriptor; }
+static InterchangeObject* MPEG2VideoDescriptor_Factory() { return new MPEG2VideoDescriptor; }
+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; }
+void
+ASDCP::MXF::Metadata_InitTypes()
+{
+ SetObjectFactory(Dict::ul(MDD_Preface), Preface_Factory);
+ SetObjectFactory(Dict::ul(MDD_IndexTableSegment), IndexTableSegment_Factory);
+
+ SetObjectFactory(Dict::ul(MDD_Identification), Identification_Factory);
+ SetObjectFactory(Dict::ul(MDD_ContentStorage), ContentStorage_Factory);
+ SetObjectFactory(Dict::ul(MDD_EssenceContainerData), EssenceContainerData_Factory);
+ SetObjectFactory(Dict::ul(MDD_MaterialPackage), MaterialPackage_Factory);
+ SetObjectFactory(Dict::ul(MDD_SourcePackage), SourcePackage_Factory);
+ SetObjectFactory(Dict::ul(MDD_StaticTrack), StaticTrack_Factory);
+ SetObjectFactory(Dict::ul(MDD_Track), Track_Factory);
+ SetObjectFactory(Dict::ul(MDD_Sequence), Sequence_Factory);
+ SetObjectFactory(Dict::ul(MDD_SourceClip), SourceClip_Factory);
+ SetObjectFactory(Dict::ul(MDD_TimecodeComponent), TimecodeComponent_Factory);
+ SetObjectFactory(Dict::ul(MDD_FileDescriptor), FileDescriptor_Factory);
+ SetObjectFactory(Dict::ul(MDD_GenericSoundEssenceDescriptor), GenericSoundEssenceDescriptor_Factory);
+ SetObjectFactory(Dict::ul(MDD_WaveAudioDescriptor), WaveAudioDescriptor_Factory);
+ SetObjectFactory(Dict::ul(MDD_GenericPictureEssenceDescriptor), GenericPictureEssenceDescriptor_Factory);
+ SetObjectFactory(Dict::ul(MDD_RGBAEssenceDescriptor), RGBAEssenceDescriptor_Factory);
+ SetObjectFactory(Dict::ul(MDD_JPEG2000PictureSubDescriptor), JPEG2000PictureSubDescriptor_Factory);
+ SetObjectFactory(Dict::ul(MDD_CDCIEssenceDescriptor), CDCIEssenceDescriptor_Factory);
+ SetObjectFactory(Dict::ul(MDD_MPEG2VideoDescriptor), MPEG2VideoDescriptor_Factory);
+ SetObjectFactory(Dict::ul(MDD_DMSegment), DMSegment_Factory);
+ 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);
+}
//------------------------------------------------------------------------------------------
// KLV Sets
//
ASDCP::Result_t
-ASDCP::MXF::Identification::InitFromTLVSet(TLVReader& TLVSet)
+Identification::InitFromTLVSet(TLVReader& TLVSet)
{
Result_t result = InterchangeObject::InitFromTLVSet(TLVSet);
if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadObject(OBJ_READ_ARGS(Identification, ThisGenerationUID));
//
ASDCP::Result_t
-ASDCP::MXF::Identification::WriteToTLVSet(TLVWriter& TLVSet)
+Identification::WriteToTLVSet(TLVWriter& TLVSet)
{
Result_t result = InterchangeObject::WriteToTLVSet(TLVSet);
if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS(Identification, ThisGenerationUID));
//
void
-ASDCP::MXF::Identification::Dump(FILE* stream)
+Identification::Dump(FILE* stream)
{
char identbuf[IdentBufferLen];
*identbuf = 0;
//
ASDCP::Result_t
-ASDCP::MXF::Identification::InitFromBuffer(const byte_t* p, ui32_t l)
+Identification::InitFromBuffer(const byte_t* p, ui32_t l)
{
m_Typeinfo = &Dict::Type(MDD_Identification);
return InterchangeObject::InitFromBuffer(p, l);
//
ASDCP::Result_t
-ASDCP::MXF::Identification::WriteToBuffer(ASDCP::FrameBuffer& Buffer)
+Identification::WriteToBuffer(ASDCP::FrameBuffer& Buffer)
{
m_Typeinfo = &Dict::Type(MDD_Identification);
return InterchangeObject::WriteToBuffer(Buffer);
//
ASDCP::Result_t
-ASDCP::MXF::ContentStorage::InitFromTLVSet(TLVReader& TLVSet)
+ContentStorage::InitFromTLVSet(TLVReader& TLVSet)
{
Result_t result = InterchangeObject::InitFromTLVSet(TLVSet);
if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadObject(OBJ_READ_ARGS(ContentStorage, Packages));
//
ASDCP::Result_t
-ASDCP::MXF::ContentStorage::WriteToTLVSet(TLVWriter& TLVSet)
+ContentStorage::WriteToTLVSet(TLVWriter& TLVSet)
{
Result_t result = InterchangeObject::WriteToTLVSet(TLVSet);
if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS(ContentStorage, Packages));
//
void
-ASDCP::MXF::ContentStorage::Dump(FILE* stream)
+ContentStorage::Dump(FILE* stream)
{
char identbuf[IdentBufferLen];
*identbuf = 0;
//
ASDCP::Result_t
-ASDCP::MXF::ContentStorage::InitFromBuffer(const byte_t* p, ui32_t l)
+ContentStorage::InitFromBuffer(const byte_t* p, ui32_t l)
{
m_Typeinfo = &Dict::Type(MDD_ContentStorage);
return InterchangeObject::InitFromBuffer(p, l);
//
ASDCP::Result_t
-ASDCP::MXF::ContentStorage::WriteToBuffer(ASDCP::FrameBuffer& Buffer)
+ContentStorage::WriteToBuffer(ASDCP::FrameBuffer& Buffer)
{
m_Typeinfo = &Dict::Type(MDD_ContentStorage);
return InterchangeObject::WriteToBuffer(Buffer);
//
ASDCP::Result_t
-ASDCP::MXF::EssenceContainerData::InitFromTLVSet(TLVReader& TLVSet)
+EssenceContainerData::InitFromTLVSet(TLVReader& TLVSet)
{
Result_t result = InterchangeObject::InitFromTLVSet(TLVSet);
if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadObject(OBJ_READ_ARGS(EssenceContainerData, LinkedPackageUID));
//
ASDCP::Result_t
-ASDCP::MXF::EssenceContainerData::WriteToTLVSet(TLVWriter& TLVSet)
+EssenceContainerData::WriteToTLVSet(TLVWriter& TLVSet)
{
Result_t result = InterchangeObject::WriteToTLVSet(TLVSet);
if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS(EssenceContainerData, LinkedPackageUID));
//
void
-ASDCP::MXF::EssenceContainerData::Dump(FILE* stream)
+EssenceContainerData::Dump(FILE* stream)
{
char identbuf[IdentBufferLen];
*identbuf = 0;
//
ASDCP::Result_t
-ASDCP::MXF::EssenceContainerData::InitFromBuffer(const byte_t* p, ui32_t l)
+EssenceContainerData::InitFromBuffer(const byte_t* p, ui32_t l)
{
m_Typeinfo = &Dict::Type(MDD_EssenceContainerData);
return InterchangeObject::InitFromBuffer(p, l);
//
ASDCP::Result_t
-ASDCP::MXF::EssenceContainerData::WriteToBuffer(ASDCP::FrameBuffer& Buffer)
+EssenceContainerData::WriteToBuffer(ASDCP::FrameBuffer& Buffer)
{
m_Typeinfo = &Dict::Type(MDD_EssenceContainerData);
return InterchangeObject::WriteToBuffer(Buffer);
//
ASDCP::Result_t
-ASDCP::MXF::GenericPackage::InitFromTLVSet(TLVReader& TLVSet)
+GenericPackage::InitFromTLVSet(TLVReader& TLVSet)
{
Result_t result = InterchangeObject::InitFromTLVSet(TLVSet);
if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadObject(OBJ_READ_ARGS(GenericPackage, PackageUID));
//
ASDCP::Result_t
-ASDCP::MXF::GenericPackage::WriteToTLVSet(TLVWriter& TLVSet)
+GenericPackage::WriteToTLVSet(TLVWriter& TLVSet)
{
Result_t result = InterchangeObject::WriteToTLVSet(TLVSet);
if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS(GenericPackage, PackageUID));
//
void
-ASDCP::MXF::GenericPackage::Dump(FILE* stream)
+GenericPackage::Dump(FILE* stream)
{
char identbuf[IdentBufferLen];
*identbuf = 0;
//
ASDCP::Result_t
-ASDCP::MXF::MaterialPackage::InitFromTLVSet(TLVReader& TLVSet)
+MaterialPackage::InitFromTLVSet(TLVReader& TLVSet)
{
Result_t result = GenericPackage::InitFromTLVSet(TLVSet);
return result;
//
ASDCP::Result_t
-ASDCP::MXF::MaterialPackage::WriteToTLVSet(TLVWriter& TLVSet)
+MaterialPackage::WriteToTLVSet(TLVWriter& TLVSet)
{
Result_t result = GenericPackage::WriteToTLVSet(TLVSet);
return result;
//
void
-ASDCP::MXF::MaterialPackage::Dump(FILE* stream)
+MaterialPackage::Dump(FILE* stream)
{
char identbuf[IdentBufferLen];
*identbuf = 0;
//
ASDCP::Result_t
-ASDCP::MXF::MaterialPackage::InitFromBuffer(const byte_t* p, ui32_t l)
+MaterialPackage::InitFromBuffer(const byte_t* p, ui32_t l)
{
m_Typeinfo = &Dict::Type(MDD_MaterialPackage);
return InterchangeObject::InitFromBuffer(p, l);
//
ASDCP::Result_t
-ASDCP::MXF::MaterialPackage::WriteToBuffer(ASDCP::FrameBuffer& Buffer)
+MaterialPackage::WriteToBuffer(ASDCP::FrameBuffer& Buffer)
{
m_Typeinfo = &Dict::Type(MDD_MaterialPackage);
return InterchangeObject::WriteToBuffer(Buffer);
//
ASDCP::Result_t
-ASDCP::MXF::SourcePackage::InitFromTLVSet(TLVReader& TLVSet)
+SourcePackage::InitFromTLVSet(TLVReader& TLVSet)
{
Result_t result = GenericPackage::InitFromTLVSet(TLVSet);
if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadObject(OBJ_READ_ARGS(SourcePackage, Descriptor));
//
ASDCP::Result_t
-ASDCP::MXF::SourcePackage::WriteToTLVSet(TLVWriter& TLVSet)
+SourcePackage::WriteToTLVSet(TLVWriter& TLVSet)
{
Result_t result = GenericPackage::WriteToTLVSet(TLVSet);
if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS(SourcePackage, Descriptor));
//
void
-ASDCP::MXF::SourcePackage::Dump(FILE* stream)
+SourcePackage::Dump(FILE* stream)
{
char identbuf[IdentBufferLen];
*identbuf = 0;
//
ASDCP::Result_t
-ASDCP::MXF::SourcePackage::InitFromBuffer(const byte_t* p, ui32_t l)
+SourcePackage::InitFromBuffer(const byte_t* p, ui32_t l)
{
m_Typeinfo = &Dict::Type(MDD_SourcePackage);
return InterchangeObject::InitFromBuffer(p, l);
//
ASDCP::Result_t
-ASDCP::MXF::SourcePackage::WriteToBuffer(ASDCP::FrameBuffer& Buffer)
+SourcePackage::WriteToBuffer(ASDCP::FrameBuffer& Buffer)
{
m_Typeinfo = &Dict::Type(MDD_SourcePackage);
return InterchangeObject::WriteToBuffer(Buffer);
//
ASDCP::Result_t
-ASDCP::MXF::GenericTrack::InitFromTLVSet(TLVReader& TLVSet)
+GenericTrack::InitFromTLVSet(TLVReader& TLVSet)
{
Result_t result = InterchangeObject::InitFromTLVSet(TLVSet);
if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadUi32(OBJ_READ_ARGS(GenericTrack, TrackID));
//
ASDCP::Result_t
-ASDCP::MXF::GenericTrack::WriteToTLVSet(TLVWriter& TLVSet)
+GenericTrack::WriteToTLVSet(TLVWriter& TLVSet)
{
Result_t result = InterchangeObject::WriteToTLVSet(TLVSet);
if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteUi32(OBJ_WRITE_ARGS(GenericTrack, TrackID));
//
void
-ASDCP::MXF::GenericTrack::Dump(FILE* stream)
+GenericTrack::Dump(FILE* stream)
{
char identbuf[IdentBufferLen];
*identbuf = 0;
//
ASDCP::Result_t
-ASDCP::MXF::StaticTrack::InitFromTLVSet(TLVReader& TLVSet)
+StaticTrack::InitFromTLVSet(TLVReader& TLVSet)
{
Result_t result = GenericTrack::InitFromTLVSet(TLVSet);
return result;
//
ASDCP::Result_t
-ASDCP::MXF::StaticTrack::WriteToTLVSet(TLVWriter& TLVSet)
+StaticTrack::WriteToTLVSet(TLVWriter& TLVSet)
{
Result_t result = GenericTrack::WriteToTLVSet(TLVSet);
return result;
//
void
-ASDCP::MXF::StaticTrack::Dump(FILE* stream)
+StaticTrack::Dump(FILE* stream)
{
char identbuf[IdentBufferLen];
*identbuf = 0;
//
ASDCP::Result_t
-ASDCP::MXF::StaticTrack::InitFromBuffer(const byte_t* p, ui32_t l)
+StaticTrack::InitFromBuffer(const byte_t* p, ui32_t l)
{
m_Typeinfo = &Dict::Type(MDD_StaticTrack);
return InterchangeObject::InitFromBuffer(p, l);
//
ASDCP::Result_t
-ASDCP::MXF::StaticTrack::WriteToBuffer(ASDCP::FrameBuffer& Buffer)
+StaticTrack::WriteToBuffer(ASDCP::FrameBuffer& Buffer)
{
m_Typeinfo = &Dict::Type(MDD_StaticTrack);
return InterchangeObject::WriteToBuffer(Buffer);
//
ASDCP::Result_t
-ASDCP::MXF::Track::InitFromTLVSet(TLVReader& TLVSet)
+Track::InitFromTLVSet(TLVReader& TLVSet)
{
Result_t result = GenericTrack::InitFromTLVSet(TLVSet);
if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadObject(OBJ_READ_ARGS(Track, EditRate));
//
ASDCP::Result_t
-ASDCP::MXF::Track::WriteToTLVSet(TLVWriter& TLVSet)
+Track::WriteToTLVSet(TLVWriter& TLVSet)
{
Result_t result = GenericTrack::WriteToTLVSet(TLVSet);
if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS(Track, EditRate));
//
void
-ASDCP::MXF::Track::Dump(FILE* stream)
+Track::Dump(FILE* stream)
{
char identbuf[IdentBufferLen];
*identbuf = 0;
//
ASDCP::Result_t
-ASDCP::MXF::Track::InitFromBuffer(const byte_t* p, ui32_t l)
+Track::InitFromBuffer(const byte_t* p, ui32_t l)
{
m_Typeinfo = &Dict::Type(MDD_Track);
return InterchangeObject::InitFromBuffer(p, l);
//
ASDCP::Result_t
-ASDCP::MXF::Track::WriteToBuffer(ASDCP::FrameBuffer& Buffer)
+Track::WriteToBuffer(ASDCP::FrameBuffer& Buffer)
{
m_Typeinfo = &Dict::Type(MDD_Track);
return InterchangeObject::WriteToBuffer(Buffer);
//
ASDCP::Result_t
-ASDCP::MXF::StructuralComponent::InitFromTLVSet(TLVReader& TLVSet)
+StructuralComponent::InitFromTLVSet(TLVReader& TLVSet)
{
Result_t result = InterchangeObject::InitFromTLVSet(TLVSet);
if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadObject(OBJ_READ_ARGS(StructuralComponent, DataDefinition));
//
ASDCP::Result_t
-ASDCP::MXF::StructuralComponent::WriteToTLVSet(TLVWriter& TLVSet)
+StructuralComponent::WriteToTLVSet(TLVWriter& TLVSet)
{
Result_t result = InterchangeObject::WriteToTLVSet(TLVSet);
if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS(StructuralComponent, DataDefinition));
//
void
-ASDCP::MXF::StructuralComponent::Dump(FILE* stream)
+StructuralComponent::Dump(FILE* stream)
{
char identbuf[IdentBufferLen];
*identbuf = 0;
//
ASDCP::Result_t
-ASDCP::MXF::Sequence::InitFromTLVSet(TLVReader& TLVSet)
+Sequence::InitFromTLVSet(TLVReader& TLVSet)
{
Result_t result = StructuralComponent::InitFromTLVSet(TLVSet);
if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadObject(OBJ_READ_ARGS(Sequence, StructuralComponents));
//
ASDCP::Result_t
-ASDCP::MXF::Sequence::WriteToTLVSet(TLVWriter& TLVSet)
+Sequence::WriteToTLVSet(TLVWriter& TLVSet)
{
Result_t result = StructuralComponent::WriteToTLVSet(TLVSet);
if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS(Sequence, StructuralComponents));
//
void
-ASDCP::MXF::Sequence::Dump(FILE* stream)
+Sequence::Dump(FILE* stream)
{
char identbuf[IdentBufferLen];
*identbuf = 0;
//
ASDCP::Result_t
-ASDCP::MXF::Sequence::InitFromBuffer(const byte_t* p, ui32_t l)
+Sequence::InitFromBuffer(const byte_t* p, ui32_t l)
{
m_Typeinfo = &Dict::Type(MDD_Sequence);
return InterchangeObject::InitFromBuffer(p, l);
//
ASDCP::Result_t
-ASDCP::MXF::Sequence::WriteToBuffer(ASDCP::FrameBuffer& Buffer)
+Sequence::WriteToBuffer(ASDCP::FrameBuffer& Buffer)
{
m_Typeinfo = &Dict::Type(MDD_Sequence);
return InterchangeObject::WriteToBuffer(Buffer);
//
ASDCP::Result_t
-ASDCP::MXF::SourceClip::InitFromTLVSet(TLVReader& TLVSet)
+SourceClip::InitFromTLVSet(TLVReader& TLVSet)
{
Result_t result = StructuralComponent::InitFromTLVSet(TLVSet);
if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadUi64(OBJ_READ_ARGS(SourceClip, StartPosition));
//
ASDCP::Result_t
-ASDCP::MXF::SourceClip::WriteToTLVSet(TLVWriter& TLVSet)
+SourceClip::WriteToTLVSet(TLVWriter& TLVSet)
{
Result_t result = StructuralComponent::WriteToTLVSet(TLVSet);
if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteUi64(OBJ_WRITE_ARGS(SourceClip, StartPosition));
//
void
-ASDCP::MXF::SourceClip::Dump(FILE* stream)
+SourceClip::Dump(FILE* stream)
{
char identbuf[IdentBufferLen];
*identbuf = 0;
//
ASDCP::Result_t
-ASDCP::MXF::SourceClip::InitFromBuffer(const byte_t* p, ui32_t l)
+SourceClip::InitFromBuffer(const byte_t* p, ui32_t l)
{
m_Typeinfo = &Dict::Type(MDD_SourceClip);
return InterchangeObject::InitFromBuffer(p, l);
//
ASDCP::Result_t
-ASDCP::MXF::SourceClip::WriteToBuffer(ASDCP::FrameBuffer& Buffer)
+SourceClip::WriteToBuffer(ASDCP::FrameBuffer& Buffer)
{
m_Typeinfo = &Dict::Type(MDD_SourceClip);
return InterchangeObject::WriteToBuffer(Buffer);
//
ASDCP::Result_t
-ASDCP::MXF::TimecodeComponent::InitFromTLVSet(TLVReader& TLVSet)
+TimecodeComponent::InitFromTLVSet(TLVReader& TLVSet)
{
Result_t result = StructuralComponent::InitFromTLVSet(TLVSet);
if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadUi16(OBJ_READ_ARGS(TimecodeComponent, RoundedTimecodeBase));
//
ASDCP::Result_t
-ASDCP::MXF::TimecodeComponent::WriteToTLVSet(TLVWriter& TLVSet)
+TimecodeComponent::WriteToTLVSet(TLVWriter& TLVSet)
{
Result_t result = StructuralComponent::WriteToTLVSet(TLVSet);
if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteUi16(OBJ_WRITE_ARGS(TimecodeComponent, RoundedTimecodeBase));
//
void
-ASDCP::MXF::TimecodeComponent::Dump(FILE* stream)
+TimecodeComponent::Dump(FILE* stream)
{
char identbuf[IdentBufferLen];
*identbuf = 0;
//
ASDCP::Result_t
-ASDCP::MXF::TimecodeComponent::InitFromBuffer(const byte_t* p, ui32_t l)
+TimecodeComponent::InitFromBuffer(const byte_t* p, ui32_t l)
{
m_Typeinfo = &Dict::Type(MDD_TimecodeComponent);
return InterchangeObject::InitFromBuffer(p, l);
//
ASDCP::Result_t
-ASDCP::MXF::TimecodeComponent::WriteToBuffer(ASDCP::FrameBuffer& Buffer)
+TimecodeComponent::WriteToBuffer(ASDCP::FrameBuffer& Buffer)
{
m_Typeinfo = &Dict::Type(MDD_TimecodeComponent);
return InterchangeObject::WriteToBuffer(Buffer);
//
ASDCP::Result_t
-ASDCP::MXF::GenericDescriptor::InitFromTLVSet(TLVReader& TLVSet)
+GenericDescriptor::InitFromTLVSet(TLVReader& TLVSet)
{
Result_t result = InterchangeObject::InitFromTLVSet(TLVSet);
if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadObject(OBJ_READ_ARGS(GenericDescriptor, Locators));
//
ASDCP::Result_t
-ASDCP::MXF::GenericDescriptor::WriteToTLVSet(TLVWriter& TLVSet)
+GenericDescriptor::WriteToTLVSet(TLVWriter& TLVSet)
{
Result_t result = InterchangeObject::WriteToTLVSet(TLVSet);
if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS(GenericDescriptor, Locators));
//
void
-ASDCP::MXF::GenericDescriptor::Dump(FILE* stream)
+GenericDescriptor::Dump(FILE* stream)
{
char identbuf[IdentBufferLen];
*identbuf = 0;
//
ASDCP::Result_t
-ASDCP::MXF::FileDescriptor::InitFromTLVSet(TLVReader& TLVSet)
+FileDescriptor::InitFromTLVSet(TLVReader& TLVSet)
{
Result_t result = GenericDescriptor::InitFromTLVSet(TLVSet);
if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadUi32(OBJ_READ_ARGS(FileDescriptor, LinkedTrackID));
//
ASDCP::Result_t
-ASDCP::MXF::FileDescriptor::WriteToTLVSet(TLVWriter& TLVSet)
+FileDescriptor::WriteToTLVSet(TLVWriter& TLVSet)
{
Result_t result = GenericDescriptor::WriteToTLVSet(TLVSet);
if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteUi32(OBJ_WRITE_ARGS(FileDescriptor, LinkedTrackID));
//
void
-ASDCP::MXF::FileDescriptor::Dump(FILE* stream)
+FileDescriptor::Dump(FILE* stream)
{
char identbuf[IdentBufferLen];
*identbuf = 0;
//
ASDCP::Result_t
-ASDCP::MXF::FileDescriptor::InitFromBuffer(const byte_t* p, ui32_t l)
+FileDescriptor::InitFromBuffer(const byte_t* p, ui32_t l)
{
m_Typeinfo = &Dict::Type(MDD_FileDescriptor);
return InterchangeObject::InitFromBuffer(p, l);
//
ASDCP::Result_t
-ASDCP::MXF::FileDescriptor::WriteToBuffer(ASDCP::FrameBuffer& Buffer)
+FileDescriptor::WriteToBuffer(ASDCP::FrameBuffer& Buffer)
{
m_Typeinfo = &Dict::Type(MDD_FileDescriptor);
return InterchangeObject::WriteToBuffer(Buffer);
//
ASDCP::Result_t
-ASDCP::MXF::GenericSoundEssenceDescriptor::InitFromTLVSet(TLVReader& TLVSet)
+GenericSoundEssenceDescriptor::InitFromTLVSet(TLVReader& TLVSet)
{
Result_t result = FileDescriptor::InitFromTLVSet(TLVSet);
if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadObject(OBJ_READ_ARGS(GenericSoundEssenceDescriptor, AudioSamplingRate));
//
ASDCP::Result_t
-ASDCP::MXF::GenericSoundEssenceDescriptor::WriteToTLVSet(TLVWriter& TLVSet)
+GenericSoundEssenceDescriptor::WriteToTLVSet(TLVWriter& TLVSet)
{
Result_t result = FileDescriptor::WriteToTLVSet(TLVSet);
if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS(GenericSoundEssenceDescriptor, AudioSamplingRate));
//
void
-ASDCP::MXF::GenericSoundEssenceDescriptor::Dump(FILE* stream)
+GenericSoundEssenceDescriptor::Dump(FILE* stream)
{
char identbuf[IdentBufferLen];
*identbuf = 0;
//
ASDCP::Result_t
-ASDCP::MXF::GenericSoundEssenceDescriptor::InitFromBuffer(const byte_t* p, ui32_t l)
+GenericSoundEssenceDescriptor::InitFromBuffer(const byte_t* p, ui32_t l)
{
m_Typeinfo = &Dict::Type(MDD_GenericSoundEssenceDescriptor);
return InterchangeObject::InitFromBuffer(p, l);
//
ASDCP::Result_t
-ASDCP::MXF::GenericSoundEssenceDescriptor::WriteToBuffer(ASDCP::FrameBuffer& Buffer)
+GenericSoundEssenceDescriptor::WriteToBuffer(ASDCP::FrameBuffer& Buffer)
{
m_Typeinfo = &Dict::Type(MDD_GenericSoundEssenceDescriptor);
return InterchangeObject::WriteToBuffer(Buffer);
//
ASDCP::Result_t
-ASDCP::MXF::WaveAudioDescriptor::InitFromTLVSet(TLVReader& TLVSet)
+WaveAudioDescriptor::InitFromTLVSet(TLVReader& TLVSet)
{
Result_t result = GenericSoundEssenceDescriptor::InitFromTLVSet(TLVSet);
if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadUi16(OBJ_READ_ARGS(WaveAudioDescriptor, BlockAlign));
//
ASDCP::Result_t
-ASDCP::MXF::WaveAudioDescriptor::WriteToTLVSet(TLVWriter& TLVSet)
+WaveAudioDescriptor::WriteToTLVSet(TLVWriter& TLVSet)
{
Result_t result = GenericSoundEssenceDescriptor::WriteToTLVSet(TLVSet);
if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteUi16(OBJ_WRITE_ARGS(WaveAudioDescriptor, BlockAlign));
//
void
-ASDCP::MXF::WaveAudioDescriptor::Dump(FILE* stream)
+WaveAudioDescriptor::Dump(FILE* stream)
{
char identbuf[IdentBufferLen];
*identbuf = 0;
//
ASDCP::Result_t
-ASDCP::MXF::WaveAudioDescriptor::InitFromBuffer(const byte_t* p, ui32_t l)
+WaveAudioDescriptor::InitFromBuffer(const byte_t* p, ui32_t l)
{
m_Typeinfo = &Dict::Type(MDD_WaveAudioDescriptor);
return InterchangeObject::InitFromBuffer(p, l);
//
ASDCP::Result_t
-ASDCP::MXF::WaveAudioDescriptor::WriteToBuffer(ASDCP::FrameBuffer& Buffer)
+WaveAudioDescriptor::WriteToBuffer(ASDCP::FrameBuffer& Buffer)
{
m_Typeinfo = &Dict::Type(MDD_WaveAudioDescriptor);
return InterchangeObject::WriteToBuffer(Buffer);
//
ASDCP::Result_t
-ASDCP::MXF::GenericPictureEssenceDescriptor::InitFromTLVSet(TLVReader& TLVSet)
+GenericPictureEssenceDescriptor::InitFromTLVSet(TLVReader& TLVSet)
{
Result_t result = FileDescriptor::InitFromTLVSet(TLVSet);
if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadUi8(OBJ_READ_ARGS(GenericPictureEssenceDescriptor, FrameLayout));
//
ASDCP::Result_t
-ASDCP::MXF::GenericPictureEssenceDescriptor::WriteToTLVSet(TLVWriter& TLVSet)
+GenericPictureEssenceDescriptor::WriteToTLVSet(TLVWriter& TLVSet)
{
Result_t result = FileDescriptor::WriteToTLVSet(TLVSet);
if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteUi8(OBJ_WRITE_ARGS(GenericPictureEssenceDescriptor, FrameLayout));
//
void
-ASDCP::MXF::GenericPictureEssenceDescriptor::Dump(FILE* stream)
+GenericPictureEssenceDescriptor::Dump(FILE* stream)
{
char identbuf[IdentBufferLen];
*identbuf = 0;
//
ASDCP::Result_t
-ASDCP::MXF::GenericPictureEssenceDescriptor::InitFromBuffer(const byte_t* p, ui32_t l)
+GenericPictureEssenceDescriptor::InitFromBuffer(const byte_t* p, ui32_t l)
{
m_Typeinfo = &Dict::Type(MDD_GenericPictureEssenceDescriptor);
return InterchangeObject::InitFromBuffer(p, l);
//
ASDCP::Result_t
-ASDCP::MXF::GenericPictureEssenceDescriptor::WriteToBuffer(ASDCP::FrameBuffer& Buffer)
+GenericPictureEssenceDescriptor::WriteToBuffer(ASDCP::FrameBuffer& Buffer)
{
m_Typeinfo = &Dict::Type(MDD_GenericPictureEssenceDescriptor);
return InterchangeObject::WriteToBuffer(Buffer);
//
ASDCP::Result_t
-ASDCP::MXF::RGBAEssenceDescriptor::InitFromTLVSet(TLVReader& TLVSet)
+RGBAEssenceDescriptor::InitFromTLVSet(TLVReader& TLVSet)
{
Result_t result = GenericPictureEssenceDescriptor::InitFromTLVSet(TLVSet);
if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadUi32(OBJ_READ_ARGS(RGBAEssenceDescriptor, ComponentMaxRef));
//
ASDCP::Result_t
-ASDCP::MXF::RGBAEssenceDescriptor::WriteToTLVSet(TLVWriter& TLVSet)
+RGBAEssenceDescriptor::WriteToTLVSet(TLVWriter& TLVSet)
{
Result_t result = GenericPictureEssenceDescriptor::WriteToTLVSet(TLVSet);
if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteUi32(OBJ_WRITE_ARGS(RGBAEssenceDescriptor, ComponentMaxRef));
//
void
-ASDCP::MXF::RGBAEssenceDescriptor::Dump(FILE* stream)
+RGBAEssenceDescriptor::Dump(FILE* stream)
{
char identbuf[IdentBufferLen];
*identbuf = 0;
//
ASDCP::Result_t
-ASDCP::MXF::RGBAEssenceDescriptor::InitFromBuffer(const byte_t* p, ui32_t l)
+RGBAEssenceDescriptor::InitFromBuffer(const byte_t* p, ui32_t l)
{
m_Typeinfo = &Dict::Type(MDD_RGBAEssenceDescriptor);
return InterchangeObject::InitFromBuffer(p, l);
//
ASDCP::Result_t
-ASDCP::MXF::RGBAEssenceDescriptor::WriteToBuffer(ASDCP::FrameBuffer& Buffer)
+RGBAEssenceDescriptor::WriteToBuffer(ASDCP::FrameBuffer& Buffer)
{
m_Typeinfo = &Dict::Type(MDD_RGBAEssenceDescriptor);
return InterchangeObject::WriteToBuffer(Buffer);
//
ASDCP::Result_t
-ASDCP::MXF::JPEG2000PictureSubDescriptor::InitFromTLVSet(TLVReader& TLVSet)
+JPEG2000PictureSubDescriptor::InitFromTLVSet(TLVReader& TLVSet)
{
Result_t result = InterchangeObject::InitFromTLVSet(TLVSet);
if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadUi16(OBJ_READ_ARGS(JPEG2000PictureSubDescriptor, Rsize));
//
ASDCP::Result_t
-ASDCP::MXF::JPEG2000PictureSubDescriptor::WriteToTLVSet(TLVWriter& TLVSet)
+JPEG2000PictureSubDescriptor::WriteToTLVSet(TLVWriter& TLVSet)
{
Result_t result = InterchangeObject::WriteToTLVSet(TLVSet);
if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteUi16(OBJ_WRITE_ARGS(JPEG2000PictureSubDescriptor, Rsize));
//
void
-ASDCP::MXF::JPEG2000PictureSubDescriptor::Dump(FILE* stream)
+JPEG2000PictureSubDescriptor::Dump(FILE* stream)
{
char identbuf[IdentBufferLen];
*identbuf = 0;
//
ASDCP::Result_t
-ASDCP::MXF::JPEG2000PictureSubDescriptor::InitFromBuffer(const byte_t* p, ui32_t l)
+JPEG2000PictureSubDescriptor::InitFromBuffer(const byte_t* p, ui32_t l)
{
m_Typeinfo = &Dict::Type(MDD_JPEG2000PictureSubDescriptor);
return InterchangeObject::InitFromBuffer(p, l);
//
ASDCP::Result_t
-ASDCP::MXF::JPEG2000PictureSubDescriptor::WriteToBuffer(ASDCP::FrameBuffer& Buffer)
+JPEG2000PictureSubDescriptor::WriteToBuffer(ASDCP::FrameBuffer& Buffer)
{
m_Typeinfo = &Dict::Type(MDD_JPEG2000PictureSubDescriptor);
return InterchangeObject::WriteToBuffer(Buffer);
//
ASDCP::Result_t
-ASDCP::MXF::CDCIEssenceDescriptor::InitFromTLVSet(TLVReader& TLVSet)
+CDCIEssenceDescriptor::InitFromTLVSet(TLVReader& TLVSet)
{
Result_t result = GenericPictureEssenceDescriptor::InitFromTLVSet(TLVSet);
if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadUi32(OBJ_READ_ARGS(CDCIEssenceDescriptor, ComponentDepth));
//
ASDCP::Result_t
-ASDCP::MXF::CDCIEssenceDescriptor::WriteToTLVSet(TLVWriter& TLVSet)
+CDCIEssenceDescriptor::WriteToTLVSet(TLVWriter& TLVSet)
{
Result_t result = GenericPictureEssenceDescriptor::WriteToTLVSet(TLVSet);
if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteUi32(OBJ_WRITE_ARGS(CDCIEssenceDescriptor, ComponentDepth));
//
void
-ASDCP::MXF::CDCIEssenceDescriptor::Dump(FILE* stream)
+CDCIEssenceDescriptor::Dump(FILE* stream)
{
char identbuf[IdentBufferLen];
*identbuf = 0;
//
ASDCP::Result_t
-ASDCP::MXF::CDCIEssenceDescriptor::InitFromBuffer(const byte_t* p, ui32_t l)
+CDCIEssenceDescriptor::InitFromBuffer(const byte_t* p, ui32_t l)
{
m_Typeinfo = &Dict::Type(MDD_CDCIEssenceDescriptor);
return InterchangeObject::InitFromBuffer(p, l);
//
ASDCP::Result_t
-ASDCP::MXF::CDCIEssenceDescriptor::WriteToBuffer(ASDCP::FrameBuffer& Buffer)
+CDCIEssenceDescriptor::WriteToBuffer(ASDCP::FrameBuffer& Buffer)
{
m_Typeinfo = &Dict::Type(MDD_CDCIEssenceDescriptor);
return InterchangeObject::WriteToBuffer(Buffer);
//
ASDCP::Result_t
-ASDCP::MXF::MPEG2VideoDescriptor::InitFromTLVSet(TLVReader& TLVSet)
+MPEG2VideoDescriptor::InitFromTLVSet(TLVReader& TLVSet)
{
Result_t result = CDCIEssenceDescriptor::InitFromTLVSet(TLVSet);
if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadUi8(OBJ_READ_ARGS(MPEG2VideoDescriptor, CodedContentType));
//
ASDCP::Result_t
-ASDCP::MXF::MPEG2VideoDescriptor::WriteToTLVSet(TLVWriter& TLVSet)
+MPEG2VideoDescriptor::WriteToTLVSet(TLVWriter& TLVSet)
{
Result_t result = CDCIEssenceDescriptor::WriteToTLVSet(TLVSet);
if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteUi8(OBJ_WRITE_ARGS(MPEG2VideoDescriptor, CodedContentType));
//
void
-ASDCP::MXF::MPEG2VideoDescriptor::Dump(FILE* stream)
+MPEG2VideoDescriptor::Dump(FILE* stream)
{
char identbuf[IdentBufferLen];
*identbuf = 0;
//
ASDCP::Result_t
-ASDCP::MXF::MPEG2VideoDescriptor::InitFromBuffer(const byte_t* p, ui32_t l)
+MPEG2VideoDescriptor::InitFromBuffer(const byte_t* p, ui32_t l)
{
m_Typeinfo = &Dict::Type(MDD_MPEG2VideoDescriptor);
return InterchangeObject::InitFromBuffer(p, l);
//
ASDCP::Result_t
-ASDCP::MXF::MPEG2VideoDescriptor::WriteToBuffer(ASDCP::FrameBuffer& Buffer)
+MPEG2VideoDescriptor::WriteToBuffer(ASDCP::FrameBuffer& Buffer)
{
m_Typeinfo = &Dict::Type(MDD_MPEG2VideoDescriptor);
return InterchangeObject::WriteToBuffer(Buffer);
//
ASDCP::Result_t
-ASDCP::MXF::DMSegment::InitFromTLVSet(TLVReader& TLVSet)
+DMSegment::InitFromTLVSet(TLVReader& TLVSet)
{
Result_t result = InterchangeObject::InitFromTLVSet(TLVSet);
+ if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadObject(OBJ_READ_ARGS(DMSegment, DataDefinition));
if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadUi64(OBJ_READ_ARGS(DMSegment, EventStartPosition));
+ if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadUi64(OBJ_READ_ARGS(DMSegment, Duration));
if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadObject(OBJ_READ_ARGS(DMSegment, EventComment));
if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadObject(OBJ_READ_ARGS(DMSegment, DMFramework));
return result;
//
ASDCP::Result_t
-ASDCP::MXF::DMSegment::WriteToTLVSet(TLVWriter& TLVSet)
+DMSegment::WriteToTLVSet(TLVWriter& TLVSet)
{
Result_t result = InterchangeObject::WriteToTLVSet(TLVSet);
+ if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS(DMSegment, DataDefinition));
if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteUi64(OBJ_WRITE_ARGS(DMSegment, EventStartPosition));
+ if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteUi64(OBJ_WRITE_ARGS(DMSegment, Duration));
if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS(DMSegment, EventComment));
if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS(DMSegment, DMFramework));
return result;
//
void
-ASDCP::MXF::DMSegment::Dump(FILE* stream)
+DMSegment::Dump(FILE* stream)
{
char identbuf[IdentBufferLen];
*identbuf = 0;
stream = stderr;
InterchangeObject::Dump(stream);
+ fprintf(stream, " %22s = %s\n", "DataDefinition", DataDefinition.EncodeString(identbuf, IdentBufferLen));
fprintf(stream, " %22s = %s\n", "EventStartPosition", i64sz(EventStartPosition, identbuf));
+ fprintf(stream, " %22s = %s\n", "Duration", i64sz(Duration, identbuf));
fprintf(stream, " %22s = %s\n", "EventComment", EventComment.EncodeString(identbuf, IdentBufferLen));
fprintf(stream, " %22s = %s\n", "DMFramework", DMFramework.EncodeString(identbuf, IdentBufferLen));
}
//
ASDCP::Result_t
-ASDCP::MXF::DMSegment::InitFromBuffer(const byte_t* p, ui32_t l)
+DMSegment::InitFromBuffer(const byte_t* p, ui32_t l)
{
m_Typeinfo = &Dict::Type(MDD_DMSegment);
return InterchangeObject::InitFromBuffer(p, l);
//
ASDCP::Result_t
-ASDCP::MXF::DMSegment::WriteToBuffer(ASDCP::FrameBuffer& Buffer)
+DMSegment::WriteToBuffer(ASDCP::FrameBuffer& Buffer)
{
m_Typeinfo = &Dict::Type(MDD_DMSegment);
return InterchangeObject::WriteToBuffer(Buffer);
//
ASDCP::Result_t
-ASDCP::MXF::CryptographicFramework::InitFromTLVSet(TLVReader& TLVSet)
+CryptographicFramework::InitFromTLVSet(TLVReader& TLVSet)
{
Result_t result = InterchangeObject::InitFromTLVSet(TLVSet);
if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadObject(OBJ_READ_ARGS(CryptographicFramework, ContextSR));
//
ASDCP::Result_t
-ASDCP::MXF::CryptographicFramework::WriteToTLVSet(TLVWriter& TLVSet)
+CryptographicFramework::WriteToTLVSet(TLVWriter& TLVSet)
{
Result_t result = InterchangeObject::WriteToTLVSet(TLVSet);
if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS(CryptographicFramework, ContextSR));
//
void
-ASDCP::MXF::CryptographicFramework::Dump(FILE* stream)
+CryptographicFramework::Dump(FILE* stream)
{
char identbuf[IdentBufferLen];
*identbuf = 0;
//
ASDCP::Result_t
-ASDCP::MXF::CryptographicFramework::InitFromBuffer(const byte_t* p, ui32_t l)
+CryptographicFramework::InitFromBuffer(const byte_t* p, ui32_t l)
{
m_Typeinfo = &Dict::Type(MDD_CryptographicFramework);
return InterchangeObject::InitFromBuffer(p, l);
//
ASDCP::Result_t
-ASDCP::MXF::CryptographicFramework::WriteToBuffer(ASDCP::FrameBuffer& Buffer)
+CryptographicFramework::WriteToBuffer(ASDCP::FrameBuffer& Buffer)
{
m_Typeinfo = &Dict::Type(MDD_CryptographicFramework);
return InterchangeObject::WriteToBuffer(Buffer);
//
ASDCP::Result_t
-ASDCP::MXF::CryptographicContext::InitFromTLVSet(TLVReader& TLVSet)
+CryptographicContext::InitFromTLVSet(TLVReader& TLVSet)
{
Result_t result = InterchangeObject::InitFromTLVSet(TLVSet);
if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadObject(OBJ_READ_ARGS(CryptographicContext, ContextID));
//
ASDCP::Result_t
-ASDCP::MXF::CryptographicContext::WriteToTLVSet(TLVWriter& TLVSet)
+CryptographicContext::WriteToTLVSet(TLVWriter& TLVSet)
{
Result_t result = InterchangeObject::WriteToTLVSet(TLVSet);
if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS(CryptographicContext, ContextID));
//
void
-ASDCP::MXF::CryptographicContext::Dump(FILE* stream)
+CryptographicContext::Dump(FILE* stream)
{
char identbuf[IdentBufferLen];
*identbuf = 0;
//
ASDCP::Result_t
-ASDCP::MXF::CryptographicContext::InitFromBuffer(const byte_t* p, ui32_t l)
+CryptographicContext::InitFromBuffer(const byte_t* p, ui32_t l)
{
m_Typeinfo = &Dict::Type(MDD_CryptographicContext);
return InterchangeObject::InitFromBuffer(p, l);
//
ASDCP::Result_t
-ASDCP::MXF::CryptographicContext::WriteToBuffer(ASDCP::FrameBuffer& Buffer)
+CryptographicContext::WriteToBuffer(ASDCP::FrameBuffer& Buffer)
{
m_Typeinfo = &Dict::Type(MDD_CryptographicContext);
return InterchangeObject::WriteToBuffer(Buffer);
}
+//------------------------------------------------------------------------------------------
+// GenericDataEssenceDescriptor
+
+//
+ASDCP::Result_t
+GenericDataEssenceDescriptor::InitFromTLVSet(TLVReader& TLVSet)
+{
+ Result_t result = FileDescriptor::InitFromTLVSet(TLVSet);
+ if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadObject(OBJ_READ_ARGS(GenericDataEssenceDescriptor, DataEssenceCoding));
+ return result;
+}
+
+//
+ASDCP::Result_t
+GenericDataEssenceDescriptor::WriteToTLVSet(TLVWriter& TLVSet)
+{
+ Result_t result = FileDescriptor::WriteToTLVSet(TLVSet);
+ if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS(GenericDataEssenceDescriptor, DataEssenceCoding));
+ return result;
+}
+
+//
+void
+GenericDataEssenceDescriptor::Dump(FILE* stream)
+{
+ char identbuf[IdentBufferLen];
+ *identbuf = 0;
+
+ if ( stream == 0 )
+ stream = stderr;
+
+ FileDescriptor::Dump(stream);
+ fprintf(stream, " %22s = %s\n", "DataEssenceCoding", DataEssenceCoding.EncodeString(identbuf, IdentBufferLen));
+}
+
+//
+ASDCP::Result_t
+GenericDataEssenceDescriptor::InitFromBuffer(const byte_t* p, ui32_t l)
+{
+ m_Typeinfo = &Dict::Type(MDD_GenericDataEssenceDescriptor);
+ return InterchangeObject::InitFromBuffer(p, l);
+}
+
+//
+ASDCP::Result_t
+GenericDataEssenceDescriptor::WriteToBuffer(ASDCP::FrameBuffer& Buffer)
+{
+ m_Typeinfo = &Dict::Type(MDD_GenericDataEssenceDescriptor);
+ return InterchangeObject::WriteToBuffer(Buffer);
+}
+
+//------------------------------------------------------------------------------------------
+// DCTimedTextDescriptor
+
+//
+ASDCP::Result_t
+DCTimedTextDescriptor::InitFromTLVSet(TLVReader& TLVSet)
+{
+ Result_t result = GenericDataEssenceDescriptor::InitFromTLVSet(TLVSet);
+ if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadObject(OBJ_READ_ARGS(DCTimedTextDescriptor, UTFEncoding));
+ if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadObject(OBJ_READ_ARGS(DCTimedTextDescriptor, RootNamespaceName));
+ return result;
+}
+
+//
+ASDCP::Result_t
+DCTimedTextDescriptor::WriteToTLVSet(TLVWriter& TLVSet)
+{
+ Result_t result = GenericDataEssenceDescriptor::WriteToTLVSet(TLVSet);
+ if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS(DCTimedTextDescriptor, UTFEncoding));
+ if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS(DCTimedTextDescriptor, RootNamespaceName));
+ return result;
+}
+
+//
+void
+DCTimedTextDescriptor::Dump(FILE* stream)
+{
+ char identbuf[IdentBufferLen];
+ *identbuf = 0;
+
+ if ( stream == 0 )
+ stream = stderr;
+
+ GenericDataEssenceDescriptor::Dump(stream);
+ fprintf(stream, " %22s = %s\n", "UTFEncoding", UTFEncoding.EncodeString(identbuf, IdentBufferLen));
+ fprintf(stream, " %22s = %s\n", "RootNamespaceName", RootNamespaceName.EncodeString(identbuf, IdentBufferLen));
+}
+
+//
+ASDCP::Result_t
+DCTimedTextDescriptor::InitFromBuffer(const byte_t* p, ui32_t l)
+{
+ m_Typeinfo = &Dict::Type(MDD_DCTimedTextDescriptor);
+ return InterchangeObject::InitFromBuffer(p, l);
+}
+
+//
+ASDCP::Result_t
+DCTimedTextDescriptor::WriteToBuffer(ASDCP::FrameBuffer& Buffer)
+{
+ m_Typeinfo = &Dict::Type(MDD_DCTimedTextDescriptor);
+ return InterchangeObject::WriteToBuffer(Buffer);
+}
+
+//------------------------------------------------------------------------------------------
+// DCTimedTextResourceDescriptor
+
+//
+ASDCP::Result_t
+DCTimedTextResourceDescriptor::InitFromTLVSet(TLVReader& TLVSet)
+{
+ Result_t result = InterchangeObject::InitFromTLVSet(TLVSet);
+ if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadObject(OBJ_READ_ARGS(DCTimedTextResourceDescriptor, ResourcePackageID));
+ if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadObject(OBJ_READ_ARGS(DCTimedTextResourceDescriptor, ResourceMIMEType));
+ if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadUi32(OBJ_READ_ARGS(DCTimedTextResourceDescriptor, ResourceSID));
+ return result;
+}
+
+//
+ASDCP::Result_t
+DCTimedTextResourceDescriptor::WriteToTLVSet(TLVWriter& TLVSet)
+{
+ Result_t result = InterchangeObject::WriteToTLVSet(TLVSet);
+ if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS(DCTimedTextResourceDescriptor, ResourcePackageID));
+ if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS(DCTimedTextResourceDescriptor, ResourceMIMEType));
+ if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteUi32(OBJ_WRITE_ARGS(DCTimedTextResourceDescriptor, ResourceSID));
+ return result;
+}
+
+//
+void
+DCTimedTextResourceDescriptor::Dump(FILE* stream)
+{
+ char identbuf[IdentBufferLen];
+ *identbuf = 0;
+
+ if ( stream == 0 )
+ stream = stderr;
+
+ InterchangeObject::Dump(stream);
+ fprintf(stream, " %22s = %s\n", "ResourcePackageID", ResourcePackageID.EncodeString(identbuf, IdentBufferLen));
+ fprintf(stream, " %22s = %s\n", "ResourceMIMEType", ResourceMIMEType.EncodeString(identbuf, IdentBufferLen));
+ fprintf(stream, " %22s = %d\n", "ResourceSID", ResourceSID);
+}
+
+//
+ASDCP::Result_t
+DCTimedTextResourceDescriptor::InitFromBuffer(const byte_t* p, ui32_t l)
+{
+ m_Typeinfo = &Dict::Type(MDD_DCTimedTextResourceDescriptor);
+ return InterchangeObject::InitFromBuffer(p, l);
+}
+
+//
+ASDCP::Result_t
+DCTimedTextResourceDescriptor::WriteToBuffer(ASDCP::FrameBuffer& Buffer)
+{
+ m_Typeinfo = &Dict::Type(MDD_DCTimedTextResourceDescriptor);
+ return InterchangeObject::WriteToBuffer(Buffer);
+}
+
+
//
// end Metadata.cpp
//
/*
-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
\brief MXF metadata objects
*/
-#ifndef _METADATA_H_
-#define _METADATA_H_
+#ifndef _Metadata_H_
+#define _Metadata_H_
#include "MXF.h"
{
namespace MXF
{
+ void Metadata_InitTypes();
+
//
//
ASDCP_NO_COPY_CONSTRUCT(DMSegment);
public:
+ UL DataDefinition;
ui64_t EventStartPosition;
+ ui64_t Duration;
UTF16String EventComment;
UUID DMFramework;
- DMSegment() : EventStartPosition(0) {}
+ DMSegment() : EventStartPosition(0), Duration(0) {}
virtual ~DMSegment() {}
virtual const char* HasName() { return "DMSegment"; }
virtual Result_t InitFromTLVSet(TLVReader& TLVSet);
virtual Result_t WriteToBuffer(ASDCP::FrameBuffer&);
};
+ //
+ class GenericDataEssenceDescriptor : public FileDescriptor
+ {
+ ASDCP_NO_COPY_CONSTRUCT(GenericDataEssenceDescriptor);
+
+ public:
+ UL DataEssenceCoding;
+
+ GenericDataEssenceDescriptor() {}
+ virtual ~GenericDataEssenceDescriptor() {}
+ virtual const char* HasName() { return "GenericDataEssenceDescriptor"; }
+ virtual Result_t InitFromTLVSet(TLVReader& TLVSet);
+ virtual Result_t WriteToTLVSet(TLVWriter& TLVSet);
+ virtual void Dump(FILE* = 0);
+ virtual Result_t InitFromBuffer(const byte_t* p, ui32_t l);
+ virtual Result_t WriteToBuffer(ASDCP::FrameBuffer&);
+ };
+
+ //
+ class DCTimedTextDescriptor : public GenericDataEssenceDescriptor
+ {
+ ASDCP_NO_COPY_CONSTRUCT(DCTimedTextDescriptor);
+
+ public:
+ UTF16String UTFEncoding;
+ UTF16String RootNamespaceName;
+
+ DCTimedTextDescriptor() {}
+ virtual ~DCTimedTextDescriptor() {}
+ virtual const char* HasName() { return "DCTimedTextDescriptor"; }
+ virtual Result_t InitFromTLVSet(TLVReader& TLVSet);
+ virtual Result_t WriteToTLVSet(TLVWriter& TLVSet);
+ virtual void Dump(FILE* = 0);
+ virtual Result_t InitFromBuffer(const byte_t* p, ui32_t l);
+ virtual Result_t WriteToBuffer(ASDCP::FrameBuffer&);
+ };
+
+ //
+ class DCTimedTextResourceDescriptor : public InterchangeObject
+ {
+ ASDCP_NO_COPY_CONSTRUCT(DCTimedTextResourceDescriptor);
+
+ public:
+ UUID ResourcePackageID;
+ UTF16String ResourceMIMEType;
+ ui32_t ResourceSID;
+
+ DCTimedTextResourceDescriptor() : ResourceSID(0) {}
+ virtual ~DCTimedTextResourceDescriptor() {}
+ virtual const char* HasName() { return "DCTimedTextResourceDescriptor"; }
+ virtual Result_t InitFromTLVSet(TLVReader& TLVSet);
+ virtual Result_t WriteToTLVSet(TLVWriter& TLVSet);
+ virtual void Dump(FILE* = 0);
+ virtual Result_t InitFromBuffer(const byte_t* p, ui32_t l);
+ virtual Result_t WriteToBuffer(ASDCP::FrameBuffer&);
+ };
} // namespace MXF
} // namespace ASDCP
-#endif // _METADATA_H_
+#endif // _Metadata_H_
//
// end Metadata.h
#include "AS_DCP_internal.h"
#include "AS_DCP_TimedText.h"
+#include "S12MTimecode.h"
#include "KM_xml.h"
using namespace Kumu;
using namespace ASDCP;
+const char* c_dcst_namespace_name = "http://www.smpte-ra.org/schemas/428-7/2007/DCST";
+
+
//------------------------------------------------------------------------------------------
-class ASDCP::TimedText::DCSubtitleParser::h__DCSubtitleParser
+typedef std::map<Kumu::UUID, TimedText::MIMEType_t> ResourceTypeMap_t;
+
+class ASDCP::TimedText::DCSubtitleParser::h__SubtitleParser
{
- ui32_t m_FileReadCount;
+ XMLElement m_Root;
+ ResourceTypeMap_t m_ResourceTypes;
- ASDCP_NO_COPY_CONSTRUCT(h__DCSubtitleParser);
+ ASDCP_NO_COPY_CONSTRUCT(h__SubtitleParser);
public:
+ std::string m_XMLDoc;
TimedTextDescriptor m_TDesc;
- h__DCSubtitleParser() : m_FileReadCount(0)
+ h__SubtitleParser() : m_Root("**ParserRoot**")
{
- memset(&m_TDesc, 0, sizeof(m_TDesc));
+ memset(&m_TDesc.AssetID, 0, UUIDlen);
}
- ~h__DCSubtitleParser()
- {
- Close();
- }
+ ~h__SubtitleParser() {}
Result_t OpenRead(const char* filename);
- void Close() {}
+ Result_t ReadAncillaryResource(const byte_t* uuid, FrameBuffer& FrameBuf) const;
+};
- Result_t Reset()
- {
- m_FileReadCount = 0;
- return RESULT_OK;
- }
+//
+bool
+get_UUID_from_element(XMLElement* Element, UUID& ID)
+{
+ assert(Element);
+ const char* p = Element->GetBody().c_str();
+ if ( strncmp(p, "urn:uuid:", 9) == 0 ) p += 9;
+ return ID.DecodeHex(p);
+}
- Result_t ReadFrame(FrameBuffer&);
-};
+//
+bool
+get_UUID_from_child_element(const char* name, XMLElement* Parent, UUID& outID)
+{
+ assert(name); assert(Parent);
+ XMLElement* Child = Parent->GetChildWithName(name);
+ if ( Child == 0 ) return false;
+ return get_UUID_from_element(Child, outID);
+}
+
+//
+static ASDCP::Rational
+decode_rational(const char* str_rat)
+{
+ assert(str_rat);
+ ui32_t Num = atoi(str_rat);
+ ui32_t Den = 0;
+
+ const char* den_str = strrchr(str_rat, ' ');
+ if ( den_str != 0 )
+ Den = atoi(den_str+1);
+
+ return ASDCP::Rational(Num, Den);
+}
+
+//
+ui32_t
+CalculateSubtitleDuration(const XMLElement* begin, const XMLElement* end)
+{
+ assert(begin); assert(end);
+
+ S12MTimecode
+ beginTC(begin->GetAttrWithName("TimeIn"), 24),
+ endTC(end->GetAttrWithName("TimeOut"), 24);
+
+ if ( endTC < beginTC )
+ return 0;
+
+ return endTC.GetFrames() - beginTC.GetFrames();
+}
+
+//
+Result_t
+ASDCP::TimedText::DCSubtitleParser::h__SubtitleParser::OpenRead(const char* filename)
+{
+ Result_t result = ReadFileIntoString(filename, m_XMLDoc);
+
+ if ( ! m_Root.ParseString(m_XMLDoc.c_str()) )
+ return RESULT_FORMAT;
+
+ m_TDesc.EncodingName = "UTF-8"; // the XML parser demands UTF-8
+ m_TDesc.ResourceList.clear();
+ m_TDesc.ContainerDuration = 0;
+ const XMLNamespace* ns = m_Root.Namespace();
+
+ if ( ns == 0 )
+ {
+ DefaultLogSink(). Warn("Document has no namespace name, assuming %s\n", c_dcst_namespace_name);
+ m_TDesc.NamespaceName = c_dcst_namespace_name;
+ }
+ else
+ m_TDesc.NamespaceName = ns->Name();
+
+ UUID DocID;
+ if ( ! get_UUID_from_child_element("Id", &m_Root, DocID) )
+ {
+ DefaultLogSink(). Error("Id element missing from input document\n");
+ return RESULT_FORMAT;
+ }
+
+ memcpy(m_TDesc.AssetID, DocID.Value(), DocID.Size());
+ XMLElement* EditRate = m_Root.GetChildWithName("EditRate");
+
+ if ( EditRate == 0 )
+ {
+ DefaultLogSink(). Error("EditRate element missing from input document\n");
+ return RESULT_FORMAT;
+ }
+
+ m_TDesc.EditRate = decode_rational(EditRate->GetBody().c_str());
+
+ // list of fonts
+ ElementList FontList;
+ m_Root.GetChildrenWithName("LoadFont", FontList);
+
+ for ( Elem_i i = FontList.begin(); i != FontList.end(); i++ )
+ {
+ UUID AssetID;
+ if ( ! get_UUID_from_element(*i, AssetID) )
+ {
+ DefaultLogSink(). Error("LoadFont element does not contain a urn:uuid value as expected.\n");
+ return RESULT_FORMAT;
+ }
+
+ TimedTextResourceDescriptor TmpResource;
+ memcpy(TmpResource.ResourceID, AssetID.Value(), UUIDlen);
+ TmpResource.Type = MT_OPENTYPE;
+ m_TDesc.ResourceList.push_back(TmpResource);
+ m_ResourceTypes.insert(ResourceTypeMap_t::value_type(UUID(TmpResource.ResourceID), MT_OPENTYPE));
+ }
+
+ // list of images
+ ElementList ImageList;
+ m_Root.GetChildrenWithName("Image", ImageList);
+
+ for ( Elem_i i = ImageList.begin(); i != ImageList.end(); i++ )
+ {
+ UUID AssetID;
+ if ( ! get_UUID_from_element(*i, AssetID) )
+ {
+ DefaultLogSink(). Error("Image element does not contain a urn:uuid value as expected.\n");
+ return RESULT_FORMAT;
+ }
+
+ TimedTextResourceDescriptor TmpResource;
+ memcpy(TmpResource.ResourceID, AssetID.Value(), UUIDlen);
+ TmpResource.Type = MT_PNG;
+ m_TDesc.ResourceList.push_back(TmpResource);
+ m_ResourceTypes.insert(ResourceTypeMap_t::value_type(UUID(TmpResource.ResourceID), MT_PNG));
+ }
+
+ // duration
+ ElementList InstanceList;
+ m_Root.GetChildrenWithName("Subtitle", InstanceList);
+ m_TDesc.ContainerDuration = CalculateSubtitleDuration(InstanceList.front(), InstanceList.back());
+
+ return RESULT_OK;
+}
+
+
+//
+Result_t
+ASDCP::TimedText::DCSubtitleParser::h__SubtitleParser::ReadAncillaryResource(const byte_t* uuid, FrameBuffer& FrameBuf) const
+{
+ FrameBuf.AssetID(uuid);
+ UUID TmpID(uuid);
+ char buf[64];
+ FileReader Reader;
+
+ ResourceTypeMap_t::const_iterator rmi = m_ResourceTypes.find(TmpID);
+
+ if ( rmi == m_ResourceTypes.end() )
+ {
+ DefaultLogSink().Error("Unknown ancillary resource id: %s\n", TmpID.EncodeHex(buf, 64));
+ return RESULT_RANGE;
+ }
+
+ Result_t result = Reader.OpenRead(TmpID.EncodeHex(buf, 64));
+
+ if ( KM_SUCCESS(result) )
+ {
+ ui32_t read_count = 0;
+ result = Reader.Read(FrameBuf.Data(), FrameBuf.Capacity(), &read_count);
+
+ if ( KM_SUCCESS(result) )
+ {
+ FrameBuf.Size(read_count);
+
+ if ( (*rmi).second == MT_PNG )
+ FrameBuf.MIMEType("image/png");
+
+ else if ( (*rmi).second == MT_OPENTYPE )
+ FrameBuf.MIMEType("application/x-opentype");
+
+ else
+ FrameBuf.MIMEType("application/octet-stream");
+ }
+ }
+ else
+ {
+ DefaultLogSink(). Error("Error opening resource file %s.\n", buf);
+ }
+
+ return result;
+}
//------------------------------------------------------------------------------------------
ASDCP::Result_t
ASDCP::TimedText::DCSubtitleParser::OpenRead(const char* filename) const
{
- const_cast<ASDCP::TimedText::DCSubtitleParser*>(this)->m_Parser = new h__DCSubtitleParser;
+ const_cast<ASDCP::TimedText::DCSubtitleParser*>(this)->m_Parser = new h__SubtitleParser;
Result_t result = m_Parser->OpenRead(filename);
if ( ASDCP_FAILURE(result) )
- const_cast<ASDCP::TimedText::DCSubtitleParser*>(this)->m_Parser.release();
+ const_cast<ASDCP::TimedText::DCSubtitleParser*>(this)->m_Parser = 0;
return result;
}
-// Rewinds the stream to the beginning.
+//
ASDCP::Result_t
-ASDCP::TimedText::DCSubtitleParser::Reset() const
+ASDCP::TimedText::DCSubtitleParser::FillDescriptor(TimedTextDescriptor& TDesc) const
{
if ( m_Parser.empty() )
return RESULT_INIT;
- return m_Parser->Reset();
+ TDesc = m_Parser->m_TDesc;
+ return RESULT_OK;
}
-// Places a frame of data in the frame buffer. Fails if the buffer is too small
-// or the stream is empty.
+// Reads the complete Timed Text Resource into the given string.
ASDCP::Result_t
-ASDCP::TimedText::DCSubtitleParser::ReadFrame(FrameBuffer& FB) const
+ASDCP::TimedText::DCSubtitleParser::ReadTimedTextResource(std::string& s) const
{
if ( m_Parser.empty() )
return RESULT_INIT;
- return m_Parser->ReadFrame(FB);
+ s = m_Parser->m_XMLDoc;
+ return RESULT_OK;
}
+//
ASDCP::Result_t
-ASDCP::TimedText::DCSubtitleParser::FillDescriptor(TimedTextDescriptor& PDesc) const
+ASDCP::TimedText::DCSubtitleParser::ReadAncillaryResource(const byte_t* uuid, FrameBuffer& FrameBuf) const
{
- if ( m_Parser.empty() )
+ if ( m_Parser.empty() )
return RESULT_INIT;
- PDesc = m_Parser->m_TDesc;
- return RESULT_OK;
+ return m_Parser->ReadAncillaryResource(uuid, FrameBuf);
}
+
//
// end AS_DCP_timedText.cpp
//
/*
-Copyright (c) 2003-2006, John Hurst
+Copyright (c) 2003-2007, John Hurst
All rights reserved.
Redistribution and use in source and binary forms, with or without
#include <WavFileWriter.h>
#include <MXF.h>
#include <Metadata.h>
+
+#ifdef ASDCP_WITH_TIMED_TEXT
+#include <AS_DCP_TimedText.h>
+#endif
+
#include <openssl/sha.h>
using namespace ASDCP;
}
+#ifdef ASDCP_WITH_TIMED_TEXT
+
+//------------------------------------------------------------------------------------------
+// TimedText essence
+
+
+// Write one or more plaintext timed text streams to a plaintext ASDCP file
+// Write one or more plaintext timed text streams to a ciphertext ASDCP file
+//
+Result_t
+write_timed_text_file(CommandOptions& Options)
+{
+ AESEncContext* Context = 0;
+ HMACContext* HMAC = 0;
+ TimedText::DCSubtitleParser Parser;
+ TimedText::MXFWriter Writer;
+ TimedText::FrameBuffer FrameBuffer;
+ TimedText::TimedTextDescriptor TDesc;
+ byte_t IV_buf[CBC_BLOCK_SIZE];
+ Kumu::FortunaRNG RNG;
+
+ // set up essence parser
+ Result_t result = Parser.OpenRead(Options.filenames[0]);
+
+ // set up MXF writer
+ if ( ASDCP_SUCCESS(result) )
+ {
+ Parser.FillDescriptor(TDesc);
+ FrameBuffer.Capacity(2*Kumu::Megabyte);
+
+ if ( Options.verbose_flag )
+ {
+ fputs("D-Cinema Timed-Text Descriptor:\n", stderr);
+ TimedText::DescriptorDump(TDesc);
+ }
+ }
+
+ if ( ASDCP_SUCCESS(result) && ! Options.no_write_flag )
+ {
+ WriterInfo Info = s_MyInfo; // fill in your favorite identifiers here
+ Kumu::GenRandomUUID(Info.AssetUUID);
+
+ if ( Options.use_smpte_labels )
+ {
+ Info.LabelSetType = LS_MXF_SMPTE;
+ fprintf(stderr, "ATTENTION! Writing SMPTE Universal Labels\n");
+ }
+
+ // configure encryption
+ if( Options.key_flag )
+ {
+ Kumu::GenRandomUUID(Info.ContextID);
+ Info.EncryptedEssence = true;
+
+ if ( Options.key_id_flag )
+ memcpy(Info.CryptographicKeyID, Options.key_id_value, UUIDlen);
+ else
+ RNG.FillRandom(Info.CryptographicKeyID, UUIDlen);
+
+ Context = new AESEncContext;
+ result = Context->InitKey(Options.key_value);
+
+ if ( ASDCP_SUCCESS(result) )
+ result = Context->SetIVec(RNG.FillRandom(IV_buf, CBC_BLOCK_SIZE));
+
+ if ( ASDCP_SUCCESS(result) && Options.write_hmac )
+ {
+ Info.UsesHMAC = true;
+ HMAC = new HMACContext;
+ result = HMAC->InitKey(Options.key_value, Info.LabelSetType);
+ }
+ }
+
+ if ( ASDCP_SUCCESS(result) )
+ result = Writer.OpenWrite(Options.out_file, Info, TDesc);
+ }
+
+ if ( ASDCP_FAILURE(result) )
+ return result;
+
+ std::string XMLDoc;
+ TimedText::ResourceList_t::const_iterator ri;
+
+ result = Parser.ReadTimedTextResource(XMLDoc);
+
+ if ( ASDCP_SUCCESS(result) )
+ result = Writer.WriteTimedTextResource(XMLDoc, Context, HMAC);
+
+ for ( ri = TDesc.ResourceList.begin() ; ri != TDesc.ResourceList.end() && ASDCP_SUCCESS(result); ri++ )
+ {
+ result = Parser.ReadAncillaryResource((*ri).ResourceID, FrameBuffer);
+
+ if ( ASDCP_SUCCESS(result) )
+ {
+ if ( Options.verbose_flag )
+ FrameBuffer.Dump(stderr, Options.fb_dump_size);
+
+ if ( ! Options.no_write_flag )
+ {
+ result = Writer.WriteAncillaryResource(FrameBuffer, Context, HMAC);
+
+ // The Writer class will forward the last block of ciphertext
+ // to the encryption context for use as the IV for the next
+ // frame. If you want to use non-sequitur IV values, un-comment
+ // the following line of code.
+ // if ( ASDCP_SUCCESS(result) && Options.key_flag )
+ // Context->SetIVec(RNG.FillRandom(IV_buf, CBC_BLOCK_SIZE));
+ }
+ }
+
+ if ( result == RESULT_ENDOFFILE )
+ result = RESULT_OK;
+ }
+
+ if ( ASDCP_SUCCESS(result) && ! Options.no_write_flag )
+ result = Writer.Finalize();
+
+ return result;
+}
+
+
+// Read one or more timed text streams from a plaintext ASDCP file
+// Read one or more timed text streams from a ciphertext ASDCP file
+// Read one or more timed text streams from a ciphertext ASDCP file
+//
+Result_t
+read_timed_text_file(CommandOptions& Options)
+{
+ AESDecContext* Context = 0;
+ HMACContext* HMAC = 0;
+ TimedText::MXFReader Reader;
+ TimedText::FrameBuffer FrameBuffer;
+ TimedText::TimedTextDescriptor TDesc;
+
+ Result_t result = Reader.OpenRead(Options.filenames[0]);
+
+ if ( ASDCP_SUCCESS(result) )
+ {
+ Reader.FillDescriptor(TDesc);
+ FrameBuffer.Capacity(2*Kumu::Megabyte);
+
+ if ( Options.verbose_flag )
+ TimedText::DescriptorDump(TDesc);
+ }
+
+ if ( ASDCP_SUCCESS(result) && Options.key_flag )
+ {
+ Context = new AESDecContext;
+ result = Context->InitKey(Options.key_value);
+
+ if ( ASDCP_SUCCESS(result) && Options.read_hmac )
+ {
+ WriterInfo Info;
+ Reader.FillWriterInfo(Info);
+
+ if ( Info.UsesHMAC )
+ {
+ HMAC = new HMACContext;
+ result = HMAC->InitKey(Options.key_value, Info.LabelSetType);
+ }
+ else
+ {
+ fputs("File does not contain HMAC values, ignoring -m option.\n", stderr);
+ }
+ }
+ }
+
+ if ( ASDCP_FAILURE(result) )
+ return result;
+
+ std::string XMLDoc;
+ TimedText::ResourceList_t::const_iterator ri;
+
+ result = Reader.ReadTimedTextResource(XMLDoc, Context, HMAC);
+
+ // do something with the XML here
+ fprintf(stderr, "XMLDoc size: %lu\n", XMLDoc.size());
+
+ for ( ri = TDesc.ResourceList.begin() ; ri != TDesc.ResourceList.end() && ASDCP_SUCCESS(result); ri++ )
+ {
+ result = Reader.ReadAncillaryResource((*ri).ResourceID, FrameBuffer, Context, HMAC);
+
+ if ( ASDCP_SUCCESS(result) )
+ {
+ // if ( Options.verbose_flag )
+ FrameBuffer.Dump(stderr, Options.fb_dump_size);
+
+ // do something with the resource data here
+ }
+ }
+
+ return result;
+}
+#endif // ASDCP_WITH_TIMED_TEXT
+
//------------------------------------------------------------------------------------------
//
}
};
+#ifdef ASDCP_WITH_TIMED_TEXT
+class MyTextDescriptor : public TimedText::TimedTextDescriptor
+{
+ public:
+ void FillDescriptor(TimedText::MXFReader& Reader) {
+ Reader.FillDescriptor(*this);
+ }
+
+ void Dump(FILE* stream) {
+ TimedText::DescriptorDump(*this, stream);
+ }
+};
+#endif
// MSVC didn't like the function template, so now it's a static class method
template<class ReaderT, class DescriptorT>
fputs("File essence type is JPEG 2000 pictures.\n", stdout);
FileInfoWrapper<ASDCP::JP2K::MXFReader, MyPictureDescriptor>::file_info(Options);
}
+#ifdef ASDCP_WITH_TIMED_TEXT
+ else if ( EssenceType == ESS_TIMED_TEXT )
+ {
+ fputs("File essence type is Timed Text.\n", stdout);
+ FileInfoWrapper<ASDCP::TimedText::MXFReader, MyTextDescriptor>::file_info(Options);
+ }
+#endif
else
{
fprintf(stderr, "File is not AS-DCP: %s\n", Options.filenames[0]);
result = read_PCM_file(Options);
break;
+ case ESS_TIMED_TEXT:
+#ifdef ASDCP_WITH_TIMED_TEXT
+ result = read_timed_text_file(Options);
+ break;
+#else
+ fprintf(stderr, "asdcplib compiled without timed text support.\n");
+ return 7;
+#endif
default:
fprintf(stderr, "%s: Unknown file type, not ASDCP essence.\n", Options.filenames[0]);
return 5;
result = write_PCM_file(Options);
break;
+ case ESS_TIMED_TEXT:
+#ifdef ASDCP_WITH_TIMED_TEXT
+ result = write_timed_text_file(Options);
+ break;
+#else
+ fprintf(stderr, "asdcplib compiled without timed text support.\n");
+ return 7;
+#endif
+
default:
fprintf(stderr, "%s: Unknown file type, not ASDCP-compatible essence.\n",
Options.filenames[0]);
{
// if this is a three partition file, go to the body
// partition and read the partition pack
- if ( m_HeaderPart.m_RIP.PairArray.size() == 3 )
+ if ( m_HeaderPart.m_RIP.PairArray.size() > 2 )
{
Array<RIP::Pair>::iterator r_i = m_HeaderPart.m_RIP.PairArray.begin();
r_i++;
// standard method of reading a plaintext or encrypted frame
Result_t
-ASDCP::h__Reader::ReadEKLVPacket(ui32_t FrameNum, ASDCP::FrameBuffer& FrameBuf,
- const byte_t* EssenceUL, AESDecContext* Ctx, HMACContext* HMAC)
+ASDCP::h__Reader::ReadEKLVFrame(ui32_t FrameNum, ASDCP::FrameBuffer& FrameBuf,
+ const byte_t* EssenceUL, AESDecContext* Ctx, HMACContext* HMAC)
{
// look up frame index node
IndexTableSegment::IndexEntry TmpEntry;
}
// get frame position and go read the frame's key and length
- Result_t result = RESULT_OK;
- KLReader Reader;
Kumu::fpos_t FilePosition = m_EssenceStart + TmpEntry.StreamOffset;
+ Result_t result = RESULT_OK;
if ( FilePosition != m_LastPosition )
{
result = m_File.Seek(FilePosition);
}
- if ( ASDCP_SUCCESS(result) )
- result = Reader.ReadKLFromFile(m_File);
+ if( ASDCP_SUCCESS(result) )
+ result = ReadEKLVPacket(FrameNum, FrameBuf, EssenceUL, Ctx, HMAC);
+
+ return result;
+}
+
+
+Result_t
+ASDCP::h__Reader::ReadEKLVPacket(ui32_t FrameNum, ASDCP::FrameBuffer& FrameBuf,
+ const byte_t* EssenceUL, AESDecContext* Ctx, HMACContext* HMAC)
+{
+ KLReader Reader;
+ Result_t result = Reader.ReadKLFromFile(m_File);
if ( ASDCP_FAILURE(result) )
return result;
//
ASDCP::h__Writer::h__Writer() :
m_HeaderSize(0), m_EssenceStart(0),
- m_MaterialPackage(0), m_MPTCSequence(0), m_MPTimecode(0), m_MPClSequence(0), m_MPClip(0),
- m_FilePackage(0), m_FPTCSequence(0), m_FPTimecode(0), m_FPClSequence(0), m_FPClip(0),
+ // m_MaterialPackage(0), m_MPTCSequence(0), m_MPTimecode(0), m_MPClSequence(0), m_MPClip(0),
+ // m_FilePackage(0), m_FPTCSequence(0), m_FPTimecode(0), m_FPClSequence(0), m_FPClip(0),
m_EssenceDescriptor(0), m_FramesWritten(0), m_StreamOffset(0)
{
}
}
//
-Result_t
-ASDCP::h__Writer::WriteMXFHeader(const std::string& PackageLabel, const UL& WrappingUL,
- const std::string& TrackName, const UL& DataDefinition,
- const MXF::Rational& EditRate,
- ui32_t TCFrameRate, ui32_t BytesPerEditUnit)
+void
+ASDCP::h__Writer::InitHeader()
{
- ASDCP_TEST_NULL(m_EssenceDescriptor);
+ assert(m_EssenceDescriptor);
m_HeaderPart.m_Primer.ClearTagList();
m_HeaderPart.m_Preface = new Preface;
Ident->ToolkitVersion.Patch = VERSION_IMPMINOR;
Ident->ToolkitVersion.Build = ASDCP_BUILD_NUMBER;
Ident->ToolkitVersion.Release = VersionType::RL_RELEASE;
+}
+
+//
+template <class ClipT>
+struct TrackSet
+{
+ MXF::Track* Track;
+ MXF::Sequence* Sequence;
+ ClipT* Clip;
+
+ TrackSet() : Track(0), Sequence(0), Clip(0) {}
+};
+
+//
+template <class PackageT, class ClipT>
+TrackSet<ClipT>
+CreateTrackAndSequence(OPAtomHeader& Header, PackageT& Package, const std::string TrackName,
+ const MXF::Rational& EditRate, const UL& Definition, ui32_t TrackID)
+{
+ TrackSet<ClipT> NewTrack;
+
+ NewTrack.Track = new Track;
+ Header.AddChildObject(NewTrack.Track);
+ NewTrack.Track->EditRate = EditRate;
+ Package.Tracks.push_back(NewTrack.Track->InstanceUID);
+ NewTrack.Track->TrackID = TrackID;
+ NewTrack.Track->TrackName = TrackName.c_str();
+
+ NewTrack.Sequence = new Sequence;
+ Header.AddChildObject(NewTrack.Sequence);
+ NewTrack.Track->Sequence = NewTrack.Sequence->InstanceUID;
+ NewTrack.Sequence->DataDefinition = Definition;
+ return NewTrack;
+}
+
+//
+template <class PackageT>
+TrackSet<TimecodeComponent>
+CreateTimecodeTrack(OPAtomHeader& Header, PackageT& Package,
+ const MXF::Rational& EditRate, ui32_t TCFrameRate, ui64_t TCStart)
+{
+ UL TCUL(Dict::ul(MDD_TimecodeDataDef));
+
+ TrackSet<TimecodeComponent> NewTrack = CreateTrackAndSequence<PackageT, TimecodeComponent>(Header, Package, "Timecode Track", EditRate, TCUL, 1);
+
+ NewTrack.Clip = new TimecodeComponent;
+ Header.AddChildObject(NewTrack.Clip);
+ NewTrack.Sequence->StructuralComponents.push_back(NewTrack.Clip->InstanceUID);
+ NewTrack.Clip->RoundedTimecodeBase = TCFrameRate;
+ NewTrack.Clip->StartTimecode = TCStart;
+ NewTrack.Clip->DataDefinition = TCUL;
+
+ return NewTrack;
+}
+
+
+//
+void
+ASDCP::h__Writer::AddSourceClip(const MXF::Rational& EditRate, ui32_t TCFrameRate,
+ const std::string& TrackName, const UL& DataDefinition,
+ const std::string& PackageLabel)
+{
//
ContentStorage* Storage = new ContentStorage;
m_HeaderPart.AddChildObject(Storage);
ECD->IndexSID = 129;
ECD->BodySID = 1;
+ UUID assetUUID(m_Info.AssetUUID);
+ UMID SourcePackageUMID, MaterialPackageUMID;
+ SourcePackageUMID.MakeUMID(0x0f, assetUUID);
+ MaterialPackageUMID.MakeUMID(0x0f); // unidentified essence
+
//
// Material Package
//
- UMID PackageUMID;
- PackageUMID.MakeUMID(0x0f); // unidentified essence
m_MaterialPackage = new MaterialPackage;
m_MaterialPackage->Name = "AS-DCP Material Package";
- m_MaterialPackage->PackageUID = PackageUMID;
+ m_MaterialPackage->PackageUID = MaterialPackageUMID;
m_HeaderPart.AddChildObject(m_MaterialPackage);
Storage->Packages.push_back(m_MaterialPackage->InstanceUID);
- // Timecode Track
- Track* NewTrack = new Track;
- m_HeaderPart.AddChildObject(NewTrack);
- NewTrack->EditRate = EditRate;
- m_MaterialPackage->Tracks.push_back(NewTrack->InstanceUID);
- NewTrack->TrackID = 1;
- NewTrack->TrackName = "Timecode Track";
-
- m_MPTCSequence = new Sequence;
- m_HeaderPart.AddChildObject(m_MPTCSequence);
- NewTrack->Sequence = m_MPTCSequence->InstanceUID;
- m_MPTCSequence->DataDefinition = UL(Dict::ul(MDD_TimecodeDataDef));
-
- m_MPTimecode = new TimecodeComponent;
- m_HeaderPart.AddChildObject(m_MPTimecode);
- m_MPTCSequence->StructuralComponents.push_back(m_MPTimecode->InstanceUID);
- m_MPTimecode->RoundedTimecodeBase = TCFrameRate;
- m_MPTimecode->StartTimecode = ui64_C(0);
- m_MPTimecode->DataDefinition = UL(Dict::ul(MDD_TimecodeDataDef));
+ TrackSet<TimecodeComponent> MPTCTrack = CreateTimecodeTrack<MaterialPackage>(m_HeaderPart, *m_MaterialPackage,
+ EditRate, TCFrameRate, 0);
+ m_DurationUpdateList.push_back(&(MPTCTrack.Sequence->Duration));
+ m_DurationUpdateList.push_back(&(MPTCTrack.Clip->Duration));
- // Essence Track
- NewTrack = new Track;
- m_HeaderPart.AddChildObject(NewTrack);
- NewTrack->EditRate = EditRate;
- m_MaterialPackage->Tracks.push_back(NewTrack->InstanceUID);
- NewTrack->TrackID = 2;
- NewTrack->TrackName = TrackName.c_str();
-
- m_MPClSequence = new Sequence;
- m_HeaderPart.AddChildObject(m_MPClSequence);
- NewTrack->Sequence = m_MPClSequence->InstanceUID;
- m_MPClSequence->DataDefinition = DataDefinition;
-
- m_MPClip = new SourceClip;
- m_HeaderPart.AddChildObject(m_MPClip);
- m_MPClSequence->StructuralComponents.push_back(m_MPClip->InstanceUID);
- m_MPClip->DataDefinition = DataDefinition;
+ TrackSet<SourceClip> MPTrack = CreateTrackAndSequence<MaterialPackage, SourceClip>(m_HeaderPart, *m_MaterialPackage,
+ TrackName, EditRate, DataDefinition, 2);
+ m_DurationUpdateList.push_back(&(MPTrack.Sequence->Duration));
+
+ MPTrack.Clip = new SourceClip;
+ m_HeaderPart.AddChildObject(MPTrack.Clip);
+ MPTrack.Sequence->StructuralComponents.push_back(MPTrack.Clip->InstanceUID);
+ MPTrack.Clip->DataDefinition = DataDefinition;
+ MPTrack.Clip->SourcePackageID = SourcePackageUMID;
+ MPTrack.Clip->SourceTrackID = 2;
+ m_DurationUpdateList.push_back(&(MPTrack.Clip->Duration));
+
//
// File (Source) Package
//
+ m_FilePackage = new SourcePackage;
+ m_FilePackage->Name = PackageLabel.c_str();
+ m_FilePackage->PackageUID = SourcePackageUMID;
+ ECD->LinkedPackageUID = SourcePackageUMID;
+
+ m_HeaderPart.AddChildObject(m_FilePackage);
+ Storage->Packages.push_back(m_FilePackage->InstanceUID);
+
+ TrackSet<TimecodeComponent> FPTCTrack = CreateTimecodeTrack<SourcePackage>(m_HeaderPart, *m_FilePackage,
+ EditRate, TCFrameRate, ui64_C(3600) * TCFrameRate);
+ m_DurationUpdateList.push_back(&(FPTCTrack.Sequence->Duration));
+ m_DurationUpdateList.push_back(&(FPTCTrack.Clip->Duration));
+
+ TrackSet<SourceClip> FPTrack = CreateTrackAndSequence<SourcePackage, SourceClip>(m_HeaderPart, *m_FilePackage,
+ TrackName, EditRate, DataDefinition, 2);
+ m_DurationUpdateList.push_back(&(FPTrack.Sequence->Duration));
+
+ FPTrack.Clip = new SourceClip;
+ m_HeaderPart.AddChildObject(FPTrack.Clip);
+ FPTrack.Sequence->StructuralComponents.push_back(FPTrack.Clip->InstanceUID);
+ FPTrack.Clip->DataDefinition = DataDefinition;
+
+ // for now we do not allow setting this value, so all files will be 'original'
+ FPTrack.Clip->SourceTrackID = 0;
+ FPTrack.Clip->SourcePackageID = NilUMID;
+ m_DurationUpdateList.push_back(&(FPTrack.Clip->Duration));
+
+ m_EssenceDescriptor->LinkedTrackID = FPTrack.Track->TrackID;
+}
+
+//
+void
+ASDCP::h__Writer::AddDMSegment(const MXF::Rational& EditRate, ui32_t TCFrameRate,
+ const std::string& TrackName, const UL& DataDefinition,
+ const std::string& PackageLabel)
+{
+ //
+ ContentStorage* Storage = new ContentStorage;
+ m_HeaderPart.AddChildObject(Storage);
+ m_HeaderPart.m_Preface->ContentStorage = Storage->InstanceUID;
+
+ EssenceContainerData* ECD = new EssenceContainerData;
+ m_HeaderPart.AddChildObject(ECD);
+ Storage->EssenceContainerData.push_back(ECD->InstanceUID);
+ ECD->IndexSID = 129;
+ ECD->BodySID = 1;
+
UUID assetUUID(m_Info.AssetUUID);
- PackageUMID.MakeUMID(0x0f, assetUUID);
+ UMID SourcePackageUMID, MaterialPackageUMID;
+ SourcePackageUMID.MakeUMID(0x0f, assetUUID);
+ MaterialPackageUMID.MakeUMID(0x0f); // unidentified essence
+
+ //
+ // Material Package
+ //
+ m_MaterialPackage = new MaterialPackage;
+ m_MaterialPackage->Name = "AS-DCP Material Package";
+ m_MaterialPackage->PackageUID = MaterialPackageUMID;
+ m_HeaderPart.AddChildObject(m_MaterialPackage);
+ Storage->Packages.push_back(m_MaterialPackage->InstanceUID);
+ TrackSet<TimecodeComponent> MPTCTrack = CreateTimecodeTrack<MaterialPackage>(m_HeaderPart, *m_MaterialPackage,
+ EditRate, TCFrameRate, 0);
+ m_DurationUpdateList.push_back(&(MPTCTrack.Sequence->Duration));
+ m_DurationUpdateList.push_back(&(MPTCTrack.Clip->Duration));
+
+ TrackSet<DMSegment> MPTrack = CreateTrackAndSequence<MaterialPackage, DMSegment>(m_HeaderPart, *m_MaterialPackage,
+ TrackName, EditRate, DataDefinition, 2);
+ m_DurationUpdateList.push_back(&(MPTrack.Sequence->Duration));
+
+ MPTrack.Clip = new DMSegment;
+ m_HeaderPart.AddChildObject(MPTrack.Clip);
+ MPTrack.Sequence->StructuralComponents.push_back(MPTrack.Clip->InstanceUID);
+ MPTrack.Clip->DataDefinition = DataDefinition;
+ // MPTrack.Clip->SourcePackageID = SourcePackageUMID;
+ // MPTrack.Clip->SourceTrackID = 2;
+ m_DurationUpdateList.push_back(&(MPTrack.Clip->Duration));
+
+
+ //
+ // File (Source) Package
+ //
m_FilePackage = new SourcePackage;
m_FilePackage->Name = PackageLabel.c_str();
- m_FilePackage->PackageUID = PackageUMID;
- ECD->LinkedPackageUID = PackageUMID;
-
- m_MPClip->SourcePackageID = PackageUMID;
- m_MPClip->SourceTrackID = 2;
+ m_FilePackage->PackageUID = SourcePackageUMID;
+ ECD->LinkedPackageUID = SourcePackageUMID;
m_HeaderPart.AddChildObject(m_FilePackage);
Storage->Packages.push_back(m_FilePackage->InstanceUID);
- // Timecode Track
- NewTrack = new Track;
- m_HeaderPart.AddChildObject(NewTrack);
- NewTrack->EditRate = EditRate;
- m_FilePackage->Tracks.push_back(NewTrack->InstanceUID);
- NewTrack->TrackID = 1;
- NewTrack->TrackName = "Timecode Track";
-
- m_FPTCSequence = new Sequence;
- m_HeaderPart.AddChildObject(m_FPTCSequence);
- NewTrack->Sequence = m_FPTCSequence->InstanceUID;
- m_FPTCSequence->DataDefinition = UL(Dict::ul(MDD_TimecodeDataDef));
-
- m_FPTimecode = new TimecodeComponent;
- m_HeaderPart.AddChildObject(m_FPTimecode);
- m_FPTCSequence->StructuralComponents.push_back(m_FPTimecode->InstanceUID);
- m_FPTimecode->RoundedTimecodeBase = TCFrameRate;
- m_FPTimecode->StartTimecode = ui64_C(86400); // 01:00:00:00
- m_FPTimecode->DataDefinition = UL(Dict::ul(MDD_TimecodeDataDef));
+ TrackSet<TimecodeComponent> FPTCTrack = CreateTimecodeTrack<SourcePackage>(m_HeaderPart, *m_FilePackage,
+ EditRate, TCFrameRate, ui64_C(3600) * TCFrameRate);
+ m_DurationUpdateList.push_back(&(FPTCTrack.Sequence->Duration));
+ m_DurationUpdateList.push_back(&(FPTCTrack.Clip->Duration));
- // Essence Track
- NewTrack = new Track;
- m_HeaderPart.AddChildObject(NewTrack);
- NewTrack->EditRate = EditRate;
- m_FilePackage->Tracks.push_back(NewTrack->InstanceUID);
- NewTrack->TrackID = 2;
- NewTrack->TrackName = TrackName.c_str();
-
- m_FPClSequence = new Sequence;
- m_HeaderPart.AddChildObject(m_FPClSequence);
- NewTrack->Sequence = m_FPClSequence->InstanceUID;
- m_FPClSequence->DataDefinition = DataDefinition;
-
- m_FPClip = new SourceClip;
- m_HeaderPart.AddChildObject(m_FPClip);
- m_FPClSequence->StructuralComponents.push_back(m_FPClip->InstanceUID);
- m_FPClip->DataDefinition = DataDefinition;
+ TrackSet<DMSegment> FPTrack = CreateTrackAndSequence<SourcePackage, DMSegment>(m_HeaderPart, *m_FilePackage,
+ TrackName, EditRate, DataDefinition, 2);
+ m_DurationUpdateList.push_back(&(FPTrack.Sequence->Duration));
- // for now we do not allow setting this value, so all files will be 'original'
- m_FPClip->SourceTrackID = 0;
- m_FPClip->SourcePackageID = NilUMID;
+ FPTrack.Clip = new DMSegment;
+ m_HeaderPart.AddChildObject(FPTrack.Clip);
+ FPTrack.Sequence->StructuralComponents.push_back(FPTrack.Clip->InstanceUID);
+ FPTrack.Clip->DataDefinition = DataDefinition;
+ FPTrack.Clip->EventComment = "D-Cinema Timed Text";
+ m_DurationUpdateList.push_back(&(FPTrack.Clip->Duration));
+ m_EssenceDescriptor->LinkedTrackID = FPTrack.Track->TrackID;
+}
+
+//
+void
+ASDCP::h__Writer::AddEssenceDescriptor(const UL& WrappingUL)
+{
//
// Essence Descriptor
//
m_EssenceDescriptor->EssenceContainer = WrappingUL;
- m_EssenceDescriptor->LinkedTrackID = NewTrack->TrackID;
m_HeaderPart.m_Preface->PrimaryPackage = m_FilePackage->InstanceUID;
//
std::list<FileDescriptor*>::iterator sdli = m_EssenceSubDescriptorList.begin();
for ( ; sdli != m_EssenceSubDescriptorList.end(); sdli++ )
- m_HeaderPart.AddChildObject(*sdli);
+ m_HeaderPart.AddChildObject(*sdli);
m_FilePackage->Descriptor = m_EssenceDescriptor->InstanceUID;
+}
- // Write the header partition
- Result_t result = m_HeaderPart.WriteToFile(m_File, m_HeaderSize);
+//
+Result_t
+ASDCP::h__Writer::CreateBodyPart(const MXF::Rational& EditRate, ui32_t BytesPerEditUnit)
+{
+ Result_t result = RESULT_OK;
- // create a body partition of we're writing proper 429-3/OP-Atom
- if ( ASDCP_SUCCESS(result) && m_Info.LabelSetType == LS_MXF_SMPTE )
+ // create a body partition if we're writing proper 429-3/OP-Atom
+ if ( m_Info.LabelSetType == LS_MXF_SMPTE )
{
// Body Partition
m_BodyPart.EssenceContainers = m_HeaderPart.EssenceContainers;
return result;
}
+//
+Result_t
+ASDCP::h__Writer::WriteMXFHeader(const std::string& PackageLabel, const UL& WrappingUL,
+ const std::string& TrackName, const UL& DataDefinition,
+ const MXF::Rational& EditRate, ui32_t TCFrameRate, ui32_t BytesPerEditUnit)
+{
+ InitHeader();
+ AddSourceClip(EditRate, TCFrameRate, TrackName, DataDefinition, PackageLabel);
+ AddEssenceDescriptor(WrappingUL);
+
+ Result_t result = m_HeaderPart.WriteToFile(m_File, m_HeaderSize);
+
+ if ( KM_SUCCESS(result) )
+ result = CreateBodyPart(EditRate, BytesPerEditUnit);
+
+ return result;
+}
// standard method of writing a plaintext or encrypted frame
{
// Set top-level file package correctly for OP-Atom
- m_MPTCSequence->Duration = m_MPTimecode->Duration = m_MPClSequence->Duration = m_MPClip->Duration =
- m_FPTCSequence->Duration = m_FPTimecode->Duration = m_FPClSequence->Duration = m_FPClip->Duration =
- m_EssenceDescriptor->ContainerDuration = m_FramesWritten;
+ // m_MPTCSequence->Duration = m_MPTimecode->Duration = m_MPClSequence->Duration = m_MPClip->Duration =
+ // m_FPTCSequence->Duration = m_FPTimecode->Duration = m_FPClSequence->Duration = m_FPClip->Duration =
+
+ DurationElementList_t::iterator dli = m_DurationUpdateList.begin();
+
+ for (; dli != m_DurationUpdateList.end(); dli++ )
+ **dli = m_FramesWritten;
+
+ m_EssenceDescriptor->ContainerDuration = m_FramesWritten;
+ m_FooterPart.PreviousPartition = m_HeaderPart.m_RIP.PairArray.back().ByteOffset;
Kumu::fpos_t here = m_File.Tell();
m_HeaderPart.m_RIP.PairArray.push_back(RIP::Pair(0, here)); // Last RIP Entry
m_HeaderPart.OperationalPattern = OPAtomUL;
m_HeaderPart.m_Preface->OperationalPattern = m_HeaderPart.OperationalPattern;
- if ( m_Info.LabelSetType == LS_MXF_SMPTE )
- m_FooterPart.PreviousPartition = m_BodyPart.ThisPartition;
- else
- m_FooterPart.PreviousPartition = m_HeaderPart.ThisPartition;
-
m_FooterPart.OperationalPattern = m_HeaderPart.OperationalPattern;
m_FooterPart.EssenceContainers = m_HeaderPart.EssenceContainers;
m_FooterPart.FooterPartition = here;
if (Options.verbose_flag)
fprintf(stderr, "Opening file %s\n", ((*fi).c_str()));
- if ( Options.read_mxf_flag )
+ if ( Options.read_mxf_flag ) // dump MXF
{
Kumu::FileReader Reader;
ASDCP::MXF::OPAtomHeader Header;
Header.Dump(stdout);
+ if ( ASDCP_SUCCESS(result) && Header.m_RIP.PairArray.size() > 3 )
+ {
+ MXF::Array<MXF::RIP::Pair>::const_iterator pi = Header.m_RIP.PairArray.begin();
+
+ for ( pi++; pi != Header.m_RIP.PairArray.end() && ASDCP_SUCCESS(result); pi++ )
+ {
+ result = Reader.Seek((*pi).ByteOffset);
+
+ if ( ASDCP_SUCCESS(result) )
+ {
+ MXF::Partition TmpPart;
+ result = TmpPart.InitFromFile(Reader);
+
+ if ( ASDCP_SUCCESS(result) && TmpPart.BodySID > 0 )
+ TmpPart.Dump(stdout);
+ }
+ }
+ }
+
if ( ASDCP_SUCCESS(result) )
{
ASDCP::MXF::OPAtomIndexFooter Index;
--- /dev/null
+/*
+Copyright (c) 2004-2007, John Hurst
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+3. The name of the author may not be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/*! \file path-test.cpp
+ \version $Id$
+ \brief test harness for path manglers defined in KM_fileio.h
+*/
+
+
+#include <KM_fileio.h>
+#include <iostream>
+
+using namespace std;
+using namespace Kumu;
+
+
+//
+int
+main(int argc, const char** argv)
+{
+
+ string Path_1 = "path-test.cpp";
+ assert(PathExists(Path_1));
+ assert(PathIsFile(Path_1));
+ assert(!PathIsDirectory(Path_1));
+
+ string Path_2 = ".";
+ assert(PathExists(Path_2));
+ assert(!PathIsFile(Path_2));
+ assert(PathIsDirectory(Path_2));
+
+ string Path_3 = "/foo/bar/baz.buz"; // must have 3 elements
+ PathCompList_t PathList_3;
+ PathToComponents(Path_3, PathList_3);
+
+ assert(PathList_3.size() == 3);
+
+ string Path_4 = ComponentsToPath(PathList_3);
+ string Path_5 = PathMakeAbsolute(Path_4);
+ string Path_6 = ComponentsToAbsolutePath(PathList_3);
+ assert(Path_3 == Path_6);
+ assert(PathsAreEquivalent(Path_3, Path_6));
+ assert(!PathsAreEquivalent(Path_3, Path_4));
+
+ assert(!PathHasComponents(PathList_3.back()));
+ assert(PathHasComponents(Path_3));
+
+ assert(!PathIsAbsolute(Path_4));
+ assert(PathIsAbsolute(Path_5));
+ assert(PathMakeLocal(Path_3, "/foo") == "bar/baz.buz");
+
+ assert(PathsAreEquivalent("/foo/bar/baz", "/foo/bar/./baz"));
+ assert(PathsAreEquivalent("/foo/baz", "/foo/bar/../baz"));
+
+ assert(PathBasename(Path_3) == "baz.buz");
+ assert(PathDirname(Path_3) == "/foo/bar");
+ assert(PathDirname("/foo") == "/");
+
+ assert(PathGetExtension(Path_3) == "buz");
+ assert(PathGetExtension("foo") == "");
+ assert(PathSetExtension("foo.bar", "") == "foo");
+ assert(PathSetExtension(Path_3, "xml") == "baz.xml");
+
+ PathList_t InList, OutList;
+ InList.push_back("tmp");
+ InList.push_back("Darwin");
+ InList.push_back(".");
+
+ cerr << "----------------------------------" << endl;
+ FindInPaths(PathMatchAny(), InList, OutList);
+ PathList_t::iterator pi;
+
+ for ( pi = OutList.begin(); pi != OutList.end(); pi++ )
+ cerr << *pi << endl;
+
+ cerr << "----------------------------------" << endl;
+ OutList.clear();
+ FindInPaths(PathMatchRegex("^[A-J].*\.h$"), InList, OutList);
+
+ for ( pi = OutList.begin(); pi != OutList.end(); pi++ )
+ cerr << *pi << endl;
+
+ cerr << "----------------------------------" << endl;
+ OutList.clear();
+ FindInPaths(PathMatchGlob("*.h"), InList, OutList);
+
+ for ( pi = OutList.begin(); pi != OutList.end(); pi++ )
+ cerr << *pi << endl;
+
+ cerr << "----------------------------------" << endl;
+
+ cerr << "OK" << endl;
+
+ return 0;
+}
+
+//
+// end path-test.cpp
+//