/*
-Copyright (c) 2011-2012, Robert Scheler, Heiko Sparenberg Fraunhofer IIS, John Hurst
+Copyright (c) 2011-2013, Robert Scheler, Heiko Sparenberg Fraunhofer IIS, John Hurst
All rights reserved.
Redistribution and use in source and binary forms, with or without
using Kumu::Result_t;
namespace MXF {
-
+#if 1
//
class OP1aIndexBodyPartion : public ASDCP::MXF::Partition
{
ASDCP::MXF::Rational m_EditRate;
ui32_t m_BodySID;
ASDCP_NO_COPY_CONSTRUCT(OP1aIndexFooter);
+ OP1aIndexFooter();
public:
const ASDCP::Dictionary*& m_Dict;
virtual void SetIndexParamsVBR(ASDCP::IPrimerLookup* lookup, const ASDCP::MXF::Rational& Rate, Kumu::fpos_t offset);
};
- } // namespace MXF
+#endif
+
+ //
+ class AS02IndexReader
+ {
+ ASDCP::MXF::IndexTableSegment* m_CurrentSegment;
+ ASDCP::FrameBuffer m_Buffer;
+ ui32_t m_BytesPerEditUnit;
+ ASDCP::Rational m_EditRate;
+ ui32_t m_BodySID;
+
+ ASDCP_NO_COPY_CONSTRUCT(AS02IndexReader);
+ AS02IndexReader();
+
+ public:
+ const ASDCP::Dictionary*& m_Dict;
+ Kumu::fpos_t m_ECOffset;
+ ASDCP::IPrimerLookup *m_Lookup;
+
+ AS02IndexReader(const ASDCP::Dictionary*&);
+ virtual ~AS02IndexReader();
+
+ virtual Result_t InitFromFile(const Kumu::FileReader& Reader);
+ virtual void Dump(FILE* = 0);
+
+ virtual Result_t GetMDObjectByID(const Kumu::UUID&, ASDCP::MXF::InterchangeObject** = 0);
+ virtual Result_t GetMDObjectByType(const byte_t*, ASDCP::MXF::InterchangeObject** = 0);
+ virtual Result_t GetMDObjectsByType(const byte_t* ObjectID, std::list<ASDCP::MXF::InterchangeObject*>& ObjectList);
+
+ virtual Result_t Lookup(ui32_t frame_num, ASDCP::MXF::IndexTableSegment::IndexEntry&) const;
+ };
+ } // namespace MXF
//---------------------------------------------------------------------------------
// Accessors in the MXFReader and MXFWriter classes below return these types to
// Warning: direct manipulation of MXF structures can interfere
// with the normal operation of the wrapper. Caveat emptor!
- virtual ASDCP::MXF::OPAtomHeader& OPAtomHeader();
+ virtual ASDCP::MXF::OP1aHeader& OP1aHeader();
+ virtual ASDCP::MXF::RIP& RIP();
// Open the file for writing. The file must not exist. Returns error if
// the operation cannot be completed or if nonsensical data is discovered
// Warning: direct manipulation of MXF structures can interfere
// with the normal operation of the wrapper. Caveat emptor!
- virtual ASDCP::MXF::OPAtomHeader& OPAtomHeader();
+ virtual ASDCP::MXF::OP1aHeader& OP1aHeader();
+ virtual AS_02::MXF::AS02IndexReader& AS02IndexReader();
+ virtual ASDCP::MXF::RIP& RIP();
// Open the file for reading. The file must exist. Returns error if the
// operation cannot be completed.
// Warning: direct manipulation of MXF structures can interfere
// with the normal operation of the wrapper. Caveat emptor!
- virtual ASDCP::MXF::OPAtomHeader& OPAtomHeader();
+ virtual ASDCP::MXF::OP1aHeader& OP1aHeader();
+ virtual ASDCP::MXF::RIP& RIP();
// Open the file for writing. The file must not exist. Returns error if
// the operation cannot be completed or if nonsensical data is discovered
// Warning: direct manipulation of MXF structures can interfere
// with the normal operation of the wrapper. Caveat emptor!
- virtual ASDCP::MXF::OPAtomHeader& OPAtomHeader();
+ virtual ASDCP::MXF::OP1aHeader& OP1aHeader();
+ virtual AS_02::MXF::AS02IndexReader& AS02IndexReader();
+ virtual ASDCP::MXF::RIP& RIP();
// Open the file for reading. The file must exist. Returns error if the
// operation cannot be completed.
/*
- Copyright (c) 2011-2012, Robert Scheler, Heiko Sparenberg Fraunhofer IIS, John Hurst
+ Copyright (c) 2011-2013, Robert Scheler, Heiko Sparenberg Fraunhofer IIS, John Hurst
All rights reserved.
Redistribution and use in source and binary forms, with or without
#include <iostream>
#include <iomanip>
+using namespace ASDCP;
using namespace ASDCP::JP2K;
using Kumu::GenRandomValue;
//------------------------------------------------------------------------------------------
-static std::string JP2K_PACKAGE_LABEL = "File Package: SMPTE 429-4 frame wrapping of JPEG 2000 codestreams";
+static std::string JP2K_PACKAGE_LABEL = "File Package: SMPTE ST 422 frame wrapping of JPEG 2000 codestreams";
static std::string PICT_DEF_LABEL = "Image Track";
//------------------------------------------------------------------------------------------
// hidden, internal implementation of JPEG 2000 reader
-class lf__Reader : public AS_02::h__Reader
+class AS_02::JP2K::MXFReader::h__Reader : public AS_02::h__AS02Reader
{
RGBAEssenceDescriptor* m_EssenceDescriptor;
JPEG2000PictureSubDescriptor* m_EssenceSubDescriptor;
ASDCP::Rational m_SampleRate;
EssenceType_t m_Format;
- ASDCP_NO_COPY_CONSTRUCT(lf__Reader);
+ ASDCP_NO_COPY_CONSTRUCT(h__Reader);
public:
PictureDescriptor m_PDesc; // codestream parameter list
- lf__Reader(const Dictionary& d) :
- AS_02::h__Reader(d), m_EssenceDescriptor(0), m_EssenceSubDescriptor(0), m_Format(ESS_UNKNOWN) {}
+ h__Reader(const Dictionary& d) :
+ AS_02::h__AS02Reader(d), m_EssenceDescriptor(0), m_EssenceSubDescriptor(0), m_Format(ESS_UNKNOWN) {}
+
+ virtual ~h__Reader() {}
+
Result_t OpenRead(const char*, EssenceType_t);
- Result_t ReadFrame(ui32_t, JP2K::FrameBuffer&, AESDecContext*, HMACContext*);
- Result_t MD_to_JP2K_PDesc(JP2K::PictureDescriptor& PDesc);
+ Result_t ReadFrame(ui32_t, ASDCP::JP2K::FrameBuffer&, AESDecContext*, HMACContext*);
+ Result_t MD_to_JP2K_PDesc(ASDCP::JP2K::PictureDescriptor& PDesc);
Result_t OpenMXFRead(const char* filename);
// positions file before reading
//
ASDCP::Result_t
-lf__Reader::MD_to_JP2K_PDesc(ASDCP::JP2K::PictureDescriptor& PDesc)
+AS_02::JP2K::MXFReader::h__Reader::MD_to_JP2K_PDesc(ASDCP::JP2K::PictureDescriptor& PDesc)
{
memset(&PDesc, 0, sizeof(PDesc));
- MXF::RGBAEssenceDescriptor* PDescObj = (MXF::RGBAEssenceDescriptor*)m_EssenceDescriptor;
+ ASDCP::MXF::RGBAEssenceDescriptor* PDescObj = (ASDCP::MXF::RGBAEssenceDescriptor*)m_EssenceDescriptor;
PDesc.EditRate = m_EditRate;
PDesc.SampleRate = m_SampleRate;
//
//
ASDCP::Result_t
-lf__Reader::OpenRead(const char* filename, ASDCP::EssenceType_t type)
+AS_02::JP2K::MXFReader::h__Reader::OpenRead(const char* filename, ASDCP::EssenceType_t type)
{
Result_t result = OpenMXFRead(filename);
return RESULT_FORMAT;
}
}
- else if ( type == ASDCP::ESS_JPEG_2000_S )
- {
- if ( m_EditRate == EditRate_24 )
- {
- if ( m_SampleRate != EditRate_48 )
- {
- DefaultLogSink().Error("EditRate and SampleRate not correct for 24/48 stereoscopic essence.\n");
- return RESULT_FORMAT;
- }
- }
- else if ( m_EditRate == EditRate_25 )
- {
- if ( m_SampleRate != EditRate_50 )
- {
- DefaultLogSink().Error("EditRate and SampleRate not correct for 25/50 stereoscopic essence.\n");
- return RESULT_FORMAT;
- }
- }
- else if ( m_EditRate == EditRate_30 )
- {
- if ( m_SampleRate != EditRate_60 )
- {
- DefaultLogSink().Error("EditRate and SampleRate not correct for 30/60 stereoscopic essence.\n");
- return RESULT_FORMAT;
- }
- }
- else
- {
- DefaultLogSink().Error("EditRate not correct for stereoscopic essence: %d/%d.\n",
- m_EditRate.Numerator, m_EditRate.Denominator);
- return RESULT_FORMAT;
- }
- }
else
{
DefaultLogSink().Error("'type' argument unexpected: %x\n", type);
result = MD_to_JP2K_PDesc(m_PDesc);
}
- if( ASDCP_SUCCESS(result) )
- result = InitMXFIndex();
-
- if( ASDCP_SUCCESS(result) )
- result = InitInfo();
-
return result;
}
//
//
ASDCP::Result_t
-lf__Reader::ReadFrame(ui32_t FrameNum, JP2K::FrameBuffer& FrameBuf,
- AESDecContext* Ctx, HMACContext* HMAC)
+AS_02::JP2K::MXFReader::h__Reader::ReadFrame(ui32_t FrameNum, ASDCP::JP2K::FrameBuffer& FrameBuf,
+ ASDCP::AESDecContext* Ctx, ASDCP::HMACContext* HMAC)
{
if ( ! m_File.IsOpen() )
return RESULT_INIT;
return ReadEKLVFrame(FrameNum, FrameBuf, m_Dict->ul(MDD_JPEG2000Essence), Ctx, HMAC);
}
-
+//------------------------------------------------------------------------------------------
//
-class AS_02::JP2K::MXFReader::h__Reader : public lf__Reader
-{
- ASDCP_NO_COPY_CONSTRUCT(h__Reader);
- h__Reader();
-
-public:
- h__Reader(const Dictionary& d) : lf__Reader(d) {}
-};
AS_02::JP2K::MXFReader::MXFReader()
{
// Warning: direct manipulation of MXF structures can interfere
// with the normal operation of the wrapper. Caveat emptor!
//
-ASDCP::MXF::OPAtomHeader&
-AS_02::JP2K::MXFReader::OPAtomHeader()
+ASDCP::MXF::OP1aHeader&
+AS_02::JP2K::MXFReader::OP1aHeader()
{
if ( m_Reader.empty() )
{
- assert(g_OPAtomHeader);
- return *g_OPAtomHeader;
+ assert(g_OP1aHeader);
+ return *g_OP1aHeader;
}
return m_Reader->m_HeaderPart;
// Warning: direct manipulation of MXF structures can interfere
// with the normal operation of the wrapper. Caveat emptor!
//
-/*
-ASDCP::MXF::OPAtomIndexFooter&
-AS_02::JP2K::MXFReader::OPAtomIndexFooter()
+AS_02::MXF::AS02IndexReader&
+AS_02::JP2K::MXFReader::AS02IndexReader()
{
if ( m_Reader.empty() )
{
- assert(g_OPAtomIndexFooter);
- return *g_OPAtomIndexFooter;
+ assert(g_AS02IndexReader);
+ return *g_AS02IndexReader;
}
- return m_Reader->m_FooterPart;
+ return m_Reader->m_IndexAccess;
+}
+
+// Warning: direct manipulation of MXF structures can interfere
+// with the normal operation of the wrapper. Caveat emptor!
+//
+ASDCP::MXF::RIP&
+AS_02::JP2K::MXFReader::RIP()
+{
+ if ( m_Reader.empty() )
+ {
+ assert(g_RIP);
+ return *g_RIP;
+ }
+
+ return m_Reader->m_RIP;
}
-*/
// Open the file for reading. The file must exist. Returns error if the
// operation cannot be completed.
-Result_t AS_02::JP2K::MXFReader::OpenRead(const char* filename) const
+Result_t
+AS_02::JP2K::MXFReader::OpenRead(const char* filename) const
{
return m_Reader->OpenRead(filename, ASDCP::ESS_JPEG_2000);
}
//
-Result_t AS_02::JP2K::MXFReader::ReadFrame(ui32_t FrameNum, ASDCP::JP2K::FrameBuffer& FrameBuf,
+Result_t
+AS_02::JP2K::MXFReader::ReadFrame(ui32_t FrameNum, ASDCP::JP2K::FrameBuffer& FrameBuf,
ASDCP::AESDecContext* Ctx, ASDCP::HMACContext* HMAC) const
{
if ( m_Reader && m_Reader->m_File.IsOpen() )
return RESULT_INIT;
}
-//
-void
-AS_02::JP2K::MXFReader::DumpHeaderMetadata(FILE* stream) const
-{
- if ( m_Reader->m_File.IsOpen() )
- m_Reader->m_HeaderPart.Dump(stream);
-}
-
-
-//
-void
-AS_02::JP2K::MXFReader::DumpIndex(FILE* stream) const
-{
- if ( m_Reader->m_File.IsOpen() )
- m_Reader->m_FooterPart.Dump(stream);
-}
-
-// standard method of opening an MXF file for read
-Result_t
-lf__Reader::OpenMXFRead(const char* filename)
-{
- m_LastPosition = 0;
- AS_02::MXF::OP1aIndexBodyPartion* pCurrentBodyPartIndex = NULL;
- Partition* pPart = NULL;
- ui64_t EssenceStart = 0;
- Result_t result = m_File.OpenRead(filename);
- if ( ASDCP_SUCCESS(result) )
- result = m_HeaderPart.InitFromFile(m_File);
-
- if ( ASDCP_SUCCESS(result) )
- {
- ui32_t partition_size = m_HeaderPart.m_RIP.PairArray.size();
-
- if ( partition_size > 3 )
- {
- //for all entry except the first and the last(header&footer)
- Array<RIP::Pair>::iterator r_i = m_HeaderPart.m_RIP.PairArray.begin();
- r_i++;
- ui32_t i=2;
-
- while(r_i != m_HeaderPart.m_RIP.PairArray.end() && i<partition_size)
- {
- m_File.Seek((*r_i).ByteOffset);
- pPart = new Partition(this->m_Dict);
- result = pPart->InitFromFile(m_File);
-
- if(pPart->BodySID != 0 && pPart->IndexSID == 0)
- { // AS_02::IS_FOLLOW
- r_i++; i++;
- EssenceStart = m_File.Tell();
-
- m_File.Seek((*r_i).ByteOffset);
- pCurrentBodyPartIndex = new AS_02::MXF::OP1aIndexBodyPartion(this->m_Dict);
- pCurrentBodyPartIndex->m_Lookup = &m_HeaderPart.m_Primer;
- result = pCurrentBodyPartIndex->InitFromFile(m_File);
- }
- else
- { // AS_02::IS_LEAD
- delete pPart;
- m_File.Seek((*r_i).ByteOffset);
- pCurrentBodyPartIndex = new AS_02::MXF::OP1aIndexBodyPartion(this->m_Dict);
- pCurrentBodyPartIndex->m_Lookup = &m_HeaderPart.m_Primer;
- result = pCurrentBodyPartIndex->InitFromFile(m_File);
-
- if ( ASDCP_FAILURE(result) )
- {
- break;
- }
-
- r_i++; i++;
- m_File.Seek((*r_i).ByteOffset);
- pPart = new Partition(this->m_Dict);
- result = pPart->InitFromFile(m_File);
- EssenceStart = m_File.Tell();
- }
-
- if ( ASDCP_FAILURE(result) )
- {
- break;
- }
-
- if(i==3)
- {
- this->m_EssenceStart = EssenceStart;
- this->m_pCurrentBodyPartition = pPart;
- this->m_pCurrentIndexPartition = pCurrentBodyPartIndex;
- }
-
- this->m_BodyPartList.push_back(pCurrentBodyPartIndex);
- this->m_BodyPartList.push_back(pPart);
- r_i++; i++;
- }
- }
- }
-
- return result;
-}
+//------------------------------------------------------------------------------------------
//
-class lf__Writer : public AS_02::h__Writer
+class AS_02::JP2K::MXFWriter::h__Writer : public AS_02::h__AS02Writer
{
- ASDCP_NO_COPY_CONSTRUCT(lf__Writer);
- lf__Writer();
+ ASDCP_NO_COPY_CONSTRUCT(h__Writer);
+ h__Writer();
JPEG2000PictureSubDescriptor* m_EssenceSubDescriptor;
AS_02::IndexStrategy_t m_IndexStrategy; //Shim parameter index_strategy_frame/clip
ui32_t m_PartitionSpace; //Shim parameter partition_spacing
- lf__Writer(const Dictionary& d) : h__Writer(d), m_EssenceSubDescriptor(0), m_IndexStrategy(AS_02::IS_FOLLOW), m_PartitionSpace(60) {
+ h__Writer(const Dictionary& d) : h__AS02Writer(d), m_EssenceSubDescriptor(0), m_IndexStrategy(AS_02::IS_FOLLOW), m_PartitionSpace(60) {
memset(m_EssenceUL, 0, SMPTE_UL_LENGTH);
}
- ~lf__Writer(){}
+ virtual ~h__Writer(){}
Result_t OpenWrite(const char*, EssenceType_t type, const AS_02::IndexStrategy_t& IndexStrategy,
const ui32_t& PartitionSpace, const ui32_t& HeaderSize);
Result_t SetSourceStream(const PictureDescriptor&, const std::string& label,
ASDCP::Rational LocalEditRate = ASDCP::Rational(0,0));
- Result_t WriteFrame(const JP2K::FrameBuffer&, bool add_index, AESEncContext*, HMACContext*);
+ Result_t WriteFrame(const ASDCP::JP2K::FrameBuffer&, bool add_index, ASDCP::AESEncContext*, ASDCP::HMACContext*);
Result_t Finalize();
- Result_t JP2K_PDesc_to_MD(JP2K::PictureDescriptor& PDesc);
+ Result_t JP2K_PDesc_to_MD(ASDCP::JP2K::PictureDescriptor& PDesc);
//void AddSourceClip(const MXF::Rational& EditRate, ui32_t TCFrameRate,
// const std::string& TrackName, const UL& EssenceUL,
//
ASDCP::Result_t
-lf__Writer::JP2K_PDesc_to_MD(JP2K::PictureDescriptor& PDesc)
+AS_02::JP2K::MXFWriter::h__Writer::JP2K_PDesc_to_MD(ASDCP::JP2K::PictureDescriptor& PDesc)
{
assert(m_EssenceDescriptor);
assert(m_EssenceSubDescriptor);
- MXF::RGBAEssenceDescriptor* PDescObj = (MXF::RGBAEssenceDescriptor*)m_EssenceDescriptor;
+ ASDCP::MXF::RGBAEssenceDescriptor* PDescObj = (ASDCP::MXF::RGBAEssenceDescriptor*)m_EssenceDescriptor;
PDescObj->ContainerDuration = PDesc.ContainerDuration;
PDescObj->SampleRate = PDesc.EditRate;
// Open the file for writing. The file must not exist. Returns error if
// the operation cannot be completed.
ASDCP::Result_t
-lf__Writer::OpenWrite(const char* filename, EssenceType_t type, const AS_02::IndexStrategy_t& IndexStrategy,
+AS_02::JP2K::MXFWriter::h__Writer::OpenWrite(const char* filename, EssenceType_t type, const AS_02::IndexStrategy_t& IndexStrategy,
const ui32_t& PartitionSpace, const ui32_t& HeaderSize)
{
if ( ! m_State.Test_BEGIN() )
// Automatically sets the MXF file's metadata from the first jpeg codestream stream.
ASDCP::Result_t
-lf__Writer::SetSourceStream(const PictureDescriptor& PDesc, const std::string& label, ASDCP::Rational LocalEditRate)
+AS_02::JP2K::MXFWriter::h__Writer::SetSourceStream(const PictureDescriptor& PDesc, const std::string& label, ASDCP::Rational LocalEditRate)
{
assert(m_Dict);
if ( ! m_State.Test_INIT() )
{
ui32_t TCFrameRate = ( m_PDesc.EditRate == EditRate_23_98 ) ? 24 : m_PDesc.EditRate.Numerator;
- result = WriteMXFHeader(label, UL(m_Dict->ul(MDD_JPEG_2000Wrapping)),
- PICT_DEF_LABEL, UL(m_EssenceUL), UL(m_Dict->ul(MDD_PictureDataDef)),
- LocalEditRate, TCFrameRate);
+ result = WriteAS02Header(label, UL(m_Dict->ul(MDD_JPEG_2000Wrapping)),
+ PICT_DEF_LABEL, UL(m_EssenceUL), UL(m_Dict->ul(MDD_PictureDataDef)),
+ LocalEditRate, TCFrameRate);
}
return result;
// error occurs.
//
ASDCP::Result_t
-lf__Writer::WriteFrame(const ASDCP::JP2K::FrameBuffer& FrameBuf, bool add_index,
+AS_02::JP2K::MXFWriter::h__Writer::WriteFrame(const ASDCP::JP2K::FrameBuffer& FrameBuf, bool add_index,
AESEncContext* Ctx, HMACContext* HMAC)
{
Result_t result = RESULT_OK;
// Closes the MXF file, writing the index and other closing information.
//
ASDCP::Result_t
-lf__Writer::Finalize()
+AS_02::JP2K::MXFWriter::h__Writer::Finalize()
{
Result_t result = RESULT_OK;
return WriteMXFFooter();
}
-
-//
-class AS_02::JP2K::MXFWriter::h__Writer : public lf__Writer
-{
- ASDCP_NO_COPY_CONSTRUCT(h__Writer);
- h__Writer();
-
-public:
- h__Writer(const Dictionary& d) : lf__Writer(d) {}
-};
-
-
//------------------------------------------------------------------------------------------
// Warning: direct manipulation of MXF structures can interfere
// with the normal operation of the wrapper. Caveat emptor!
//
-ASDCP::MXF::OPAtomHeader&
-AS_02::JP2K::MXFWriter::OPAtomHeader()
+ASDCP::MXF::OP1aHeader&
+AS_02::JP2K::MXFWriter::OP1aHeader()
{
if ( m_Writer.empty() )
{
- assert(g_OPAtomHeader);
- return *g_OPAtomHeader;
+ assert(g_OP1aHeader);
+ return *g_OP1aHeader;
}
return m_Writer->m_HeaderPart;
// Warning: direct manipulation of MXF structures can interfere
// with the normal operation of the wrapper. Caveat emptor!
//
-/*
-ASDCP::MXF::OPAtomIndexFooter&
-AS_02::JP2K::MXFWriter::OPAtomIndexFooter()
+ASDCP::MXF::RIP&
+AS_02::JP2K::MXFWriter::RIP()
{
if ( m_Writer.empty() )
{
- assert(g_OPAtomIndexFooter);
- return *g_OPAtomIndexFooter;
+ assert(g_RIP);
+ return *g_RIP;
}
- return m_Writer->m_FooterPart;
+ return m_Writer->m_RIP;
}
-*/
// Open the file for writing. The file must not exist. Returns error if
// the operation cannot be completed.
}
-//------------------------------------------------------------------------------------------
-
-// standard method of reading a plaintext or encrypted frame
-Result_t
-lf__Reader::ReadEKLVFrame(ui32_t FrameNum, ASDCP::FrameBuffer& FrameBuf,
- const byte_t* EssenceUL, AESDecContext* Ctx, HMACContext* HMAC)
-{
- Result_t result = RESULT_OK;
- IndexTableSegment::IndexEntry TmpEntry;
-
- assert(m_pCurrentIndexPartition != NULL);
-
- if( m_pCurrentIndexPartition->Lookup(FrameNum, TmpEntry, m_start_pos) == false)
- {
- m_start_pos = 0;
-
- //compute new indexPartition for this FrameNum
- for (ui32_t i = 0; i < m_BodyPartList.size(); i+=2 )
- {
- if( m_IndexStrategy == AS_02::IS_FOLLOW )
- {
- m_pCurrentBodyPartition = m_BodyPartList.at(i);
- m_pCurrentIndexPartition = dynamic_cast<AS_02::MXF::OP1aIndexBodyPartion*> (m_BodyPartList.at(i+1));
- }
- else if( m_IndexStrategy == AS_02::IS_LEAD )
- {
- m_pCurrentIndexPartition = dynamic_cast<AS_02::MXF::OP1aIndexBodyPartion*> (m_BodyPartList.at(i));
- m_pCurrentBodyPartition = m_BodyPartList.at(i+1);
- }
- else
- {
- return RESULT_FORMAT; //return error
- }
-
- if( m_pCurrentIndexPartition == 0 )
- return RESULT_FORMAT;
-
- if(m_pCurrentIndexPartition->Lookup(FrameNum, TmpEntry, m_start_pos))
- {
- if ( FrameNum % m_PartitionSpace == 0 )
- {
- ui64_t offset = m_pCurrentBodyPartition->ThisPartition - m_pCurrentBodyPartition->PreviousPartition;
- offset += m_pCurrentBodyPartition->ArchiveSize();//Offset for the BodyPartitionHeader - Partition::ArchiveSize();
- m_EssenceStart += offset;
- }
- break;
- }
- }
- }
-
- // get frame position and go read the frame's key and length
- Kumu::fpos_t FilePosition = this->m_EssenceStart + TmpEntry.StreamOffset;
-
- if ( FilePosition != m_LastPosition )
- {
- m_LastPosition = FilePosition;
- result = m_File.Seek(FilePosition);
- }
-
- if( ASDCP_SUCCESS(result) )
- result = ReadEKLVPacket(FrameNum, FrameNum + 1, FrameBuf, EssenceUL, Ctx, HMAC);
-
- return result;
-}
-
-//
-Result_t
-lf__Reader::ReadEKLVPacket(ui32_t FrameNum, ui32_t SequenceNum, 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;
-
- UL Key(Reader.Key());
- ui64_t PacketLength = Reader.Length();
- m_LastPosition = m_LastPosition + Reader.KLLength() + PacketLength;
- assert(m_Dict);
-
- if ( memcmp(Key.Value(), m_Dict->ul(MDD_CryptEssence), Key.Size() - 1) == 0 ) // ignore the stream numbers
- {
- if ( ! m_Info.EncryptedEssence )
- {
- DefaultLogSink().Error("EKLV packet found, no Cryptographic Context in header.\n");
- return RESULT_FORMAT;
- }
-
- // read encrypted triplet value into internal buffer
- assert(PacketLength <= 0xFFFFFFFFL);
- m_CtFrameBuf.Capacity((ui32_t) PacketLength);
- ui32_t read_count;
- result = m_File.Read(m_CtFrameBuf.Data(), (ui32_t) PacketLength,
- &read_count);
-
- if ( ASDCP_FAILURE(result) )
- return result;
-
- if ( read_count != PacketLength )
- {
- DefaultLogSink().Error("read length is smaller than EKLV packet length.\n");
- return RESULT_FORMAT;
- }
-
- m_CtFrameBuf.Size((ui32_t) PacketLength);
-
- // should be const but mxflib::ReadBER is not
- byte_t* ess_p = m_CtFrameBuf.Data();
-
- // read context ID length
- if ( ! Kumu::read_test_BER(&ess_p, UUIDlen) )
- return RESULT_FORMAT;
-
- // test the context ID
- if ( memcmp(ess_p, m_Info.ContextID, UUIDlen) != 0 )
- {
- DefaultLogSink().Error("Packet's Cryptographic Context ID does not match the header.\n");
- return RESULT_FORMAT;
- }
- ess_p += UUIDlen;
-
- // read PlaintextOffset length
- if ( ! Kumu::read_test_BER(&ess_p, sizeof(ui64_t)) )
- return RESULT_FORMAT;
-
- ui32_t PlaintextOffset = (ui32_t)KM_i64_BE(Kumu::cp2i<ui64_t>(ess_p));
- ess_p += sizeof(ui64_t);
-
- // read essence UL length
- if ( ! Kumu::read_test_BER(&ess_p, SMPTE_UL_LENGTH) )
- return RESULT_FORMAT;
-
- // test essence UL
- if ( memcmp(ess_p, EssenceUL, SMPTE_UL_LENGTH - 1) != 0 ) // ignore the stream number
- {
- char strbuf[IntBufferLen];
- const MDDEntry* Entry = m_Dict->FindUL(Key.Value());
- if ( Entry == 0 )
- DefaultLogSink().Warn("Unexpected Essence UL found: %s.\n", Key.EncodeString(strbuf, IntBufferLen));
- else
- DefaultLogSink().Warn("Unexpected Essence UL found: %s.\n", Entry->name);
- return RESULT_FORMAT;
- }
- ess_p += SMPTE_UL_LENGTH;
-
- // read SourceLength length
- if ( ! Kumu::read_test_BER(&ess_p, sizeof(ui64_t)) )
- return RESULT_FORMAT;
-
- ui32_t SourceLength = (ui32_t)KM_i64_BE(Kumu::cp2i<ui64_t>(ess_p));
- ess_p += sizeof(ui64_t);
- assert(SourceLength);
-
- if ( FrameBuf.Capacity() < SourceLength )
- {
- DefaultLogSink().Error("FrameBuf.Capacity: %u SourceLength: %u\n", FrameBuf.Capacity(), SourceLength);
- return RESULT_SMALLBUF;
- }
-
- ui32_t esv_length = calc_esv_length(SourceLength, PlaintextOffset);
-
- // read ESV length
- if ( ! Kumu::read_test_BER(&ess_p, esv_length) )
- {
- DefaultLogSink().Error("read_test_BER did not return %u\n", esv_length);
- return RESULT_FORMAT;
- }
-
- ui32_t tmp_len = esv_length + (m_Info.UsesHMAC ? klv_intpack_size : 0);
-
- if ( PacketLength < tmp_len )
- {
- DefaultLogSink().Error("Frame length is larger than EKLV packet length.\n");
- return RESULT_FORMAT;
- }
-
- if ( Ctx )
- {
- // wrap the pointer and length as a FrameBuffer for use by
- // DecryptFrameBuffer() and TestValues()
- ASDCP::FrameBuffer TmpWrapper;
- TmpWrapper.SetData(ess_p, tmp_len);
- TmpWrapper.Size(tmp_len);
- TmpWrapper.SourceLength(SourceLength);
- TmpWrapper.PlaintextOffset(PlaintextOffset);
-
- result = DecryptFrameBuffer(TmpWrapper, FrameBuf, Ctx);
- FrameBuf.FrameNumber(FrameNum);
-
- // detect and test integrity pack
- if ( ASDCP_SUCCESS(result) && m_Info.UsesHMAC && HMAC )
- {
- IntegrityPack IntPack;
- result = IntPack.TestValues(TmpWrapper, m_Info.AssetUUID, SequenceNum, HMAC);
- }
- }
- else // return ciphertext to caller
- {
- if ( FrameBuf.Capacity() < tmp_len )
- {
- char intbuf[IntBufferLen];
- DefaultLogSink().Error("FrameBuf.Capacity: %u FrameLength: %s\n",
- FrameBuf.Capacity(), ui64sz(PacketLength, intbuf));
- return RESULT_SMALLBUF;
- }
-
- memcpy(FrameBuf.Data(), ess_p, tmp_len);
- FrameBuf.Size(tmp_len);
- FrameBuf.FrameNumber(FrameNum);
- FrameBuf.SourceLength(SourceLength);
- FrameBuf.PlaintextOffset(PlaintextOffset);
- }
- }
- else if ( memcmp(Key.Value(), EssenceUL, Key.Size() - 1) == 0 ) // ignore the stream number
- { // read plaintext frame
- if ( FrameBuf.Capacity() < PacketLength )
- {
- char intbuf[IntBufferLen];
- DefaultLogSink().Error("FrameBuf.Capacity: %u FrameLength: %s\n",
- FrameBuf.Capacity(), ui64sz(PacketLength, intbuf));
- return RESULT_SMALLBUF;
- }
-
- // read the data into the supplied buffer
- ui32_t read_count;
- assert(PacketLength <= 0xFFFFFFFFL);
- result = m_File.Read(FrameBuf.Data(), (ui32_t) PacketLength, &read_count);
-
- if ( ASDCP_FAILURE(result) )
- return result;
-
- if ( read_count != PacketLength )
- {
- char intbuf1[IntBufferLen];
- char intbuf2[IntBufferLen];
- DefaultLogSink().Error("read_count: %s != FrameLength: %s\n",
- ui64sz(read_count, intbuf1),
- ui64sz(PacketLength, intbuf2) );
-
- return RESULT_READFAIL;
- }
-
- FrameBuf.FrameNumber(FrameNum);
- FrameBuf.Size(read_count);
- }
- else
- {
- char strbuf[IntBufferLen];
- const MDDEntry* Entry = m_Dict->FindUL(Key.Value());
- if ( Entry == 0 )
- DefaultLogSink().Warn("Unexpected Essence UL found: %s.\n", Key.EncodeString(strbuf, IntBufferLen));
- else
- DefaultLogSink().Warn("Unexpected Essence UL found: %s.\n", Entry->name);
- return RESULT_FORMAT;
- }
-
- return result;
-}
-
-
-// standard method of writing the header and footer of a completed MXF file
-//
-Result_t
-lf__Writer::WriteMXFFooter()
-{
- // 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 =
-
- 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.FooterPartition = here;
-
- assert(m_Dict);
- // re-label the partition
- UL OPAtomUL(m_Dict->ul(MDD_OP1a));
- m_HeaderPart.OperationalPattern = OPAtomUL;
- m_HeaderPart.m_Preface->OperationalPattern = m_HeaderPart.OperationalPattern;
-
- m_FooterPart.OperationalPattern = m_HeaderPart.OperationalPattern;
- m_FooterPart.EssenceContainers = m_HeaderPart.EssenceContainers;
- m_FooterPart.FooterPartition = here;
- m_FooterPart.ThisPartition = here;
-
- Result_t result = m_FooterPart.WriteToFile(m_File, m_FramesWritten);
-
- if ( ASDCP_SUCCESS(result) )
- result = m_HeaderPart.m_RIP.WriteToFile(m_File);
-
- if ( ASDCP_SUCCESS(result) )
- result = m_File.Seek(0);
-
- if ( ASDCP_SUCCESS(result) )
- result = m_HeaderPart.WriteToFile(m_File, m_HeaderSize);
-
- //update the value of FooterPartition in all Partitions
- std::vector<Partition*>::iterator iter = this->m_BodyPartList.begin();
- for (; iter != this->m_BodyPartList.end(); iter++ ){
- (*iter)->FooterPartition = m_FooterPart.ThisPartition;
- if ( ASDCP_SUCCESS(result) )
- result = m_File.Seek((*iter)->ThisPartition);
- if ( ASDCP_SUCCESS(result) ){
- UL BodyUL(m_Dict->ul(MDD_ClosedCompleteBodyPartition));
- result = (*iter)->WriteToFile(m_File, BodyUL);
- }
- }
-
- m_File.Close();
- return result;
-}
-
//
// end AS_02_JP2K.cpp
//
/*
- Copyright (c) 2011-2012, Robert Scheler, Heiko Sparenberg Fraunhofer IIS, John Hurst
+ Copyright (c) 2011-2013, Robert Scheler, Heiko Sparenberg Fraunhofer IIS, John Hurst
All rights reserved.
Redistribution and use in source and binary forms, with or without
static std::string PCM_PACKAGE_LABEL = "File Package: SMPTE 382M clip wrapping of wave audio";
static std::string SOUND_DEF_LABEL = "Sound Track";
-static byte_t SNDFMT_CFG_1_UL[16] = { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x0b,
- 0x04, 0x02, 0x02, 0x10, 0x03, 0x01, 0x01, 0x00 };
-
-static byte_t SNDFMT_CFG_2_UL[16] = { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x0b,
- 0x04, 0x02, 0x02, 0x10, 0x03, 0x01, 0x02, 0x00 };
-
-static byte_t SNDFMT_CFG_3_UL[16] = { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x0b,
- 0x04, 0x02, 0x02, 0x10, 0x03, 0x01, 0x03, 0x00 };
-
//this must be changed because the CBR_frame_size is only
//
static ui32_t
//------------------------------------------------------------------------------------------
-class AS_02::PCM::MXFReader::h__Reader : public AS_02::h__Reader
+class AS_02::PCM::MXFReader::h__Reader : public AS_02::h__AS02Reader
{
ASDCP_NO_COPY_CONSTRUCT(h__Reader);
h__Reader();
public:
ASDCP::PCM::AudioDescriptor m_ADesc;
- h__Reader(const Dictionary& d) : AS_02::h__Reader(d) {}
- ~h__Reader() {}
+ h__Reader(const Dictionary& d) : AS_02::h__AS02Reader(d) {}
+ virtual ~h__Reader() {}
+
ASDCP::Result_t OpenRead(const char*);
ASDCP::Result_t ReadFrame(ui32_t, ASDCP::PCM::FrameBuffer&, ASDCP::AESDecContext*, ASDCP::HMACContext*);
}
}
- if( ASDCP_SUCCESS(result) )
- result = InitMXFIndex();
-
- if( ASDCP_SUCCESS(result) )
- result = InitInfo();
-
// TODO: test file for sane CBR index BytesPerEditUnit
return result;
// Warning: direct manipulation of MXF structures can interfere
// with the normal operation of the wrapper. Caveat emptor!
//
-ASDCP::MXF::OPAtomHeader&
-AS_02::PCM::MXFReader::OPAtomHeader()
+ASDCP::MXF::OP1aHeader&
+AS_02::PCM::MXFReader::OP1aHeader()
{
if ( m_Reader.empty() )
{
- assert(g_OPAtomHeader);
- return *g_OPAtomHeader;
+ assert(g_OP1aHeader);
+ return *g_OP1aHeader;
}
return m_Reader->m_HeaderPart;
// Warning: direct manipulation of MXF structures can interfere
// with the normal operation of the wrapper. Caveat emptor!
//
-/*
-ASDCP::MXF::OPAtomIndexFooter&
-AS_02::PCM::MXFReader::OPAtomIndexFooter()
+AS_02::MXF::AS02IndexReader&
+AS_02::PCM::MXFReader::AS02IndexReader()
{
if ( m_Reader.empty() )
{
- assert(g_OPAtomIndexFooter);
- return *g_OPAtomIndexFooter;
+ assert(g_AS02IndexReader);
+ return *g_AS02IndexReader;
}
- return m_Reader->m_FooterPart;
+ return m_Reader->m_IndexAccess;
+}
+
+// Warning: direct manipulation of MXF structures can interfere
+// with the normal operation of the wrapper. Caveat emptor!
+//
+ASDCP::MXF::RIP&
+AS_02::PCM::MXFReader::RIP()
+{
+ if ( m_Reader.empty() )
+ {
+ assert(g_RIP);
+ return *g_RIP;
+ }
+
+ return m_Reader->m_RIP;
}
-*/
// Open the file for reading. The file must exist. Returns error if the
// operation cannot be completed.
AS_02::PCM::MXFReader::DumpIndex(FILE* stream) const
{
if ( m_Reader->m_File.IsOpen() )
- m_Reader->m_FooterPart.Dump(stream);
+ m_Reader->m_IndexAccess.Dump(stream);
}
//------------------------------------------------------------------------------------------
//
-class AS_02::PCM::MXFWriter::h__Writer : public AS_02::h__Writer
+class AS_02::PCM::MXFWriter::h__Writer : public AS_02::h__AS02Writer
{
ASDCP_NO_COPY_CONSTRUCT(h__Writer);
h__Writer();
byte_t m_EssenceUL[SMPTE_UL_LENGTH];
ui64_t m_KLV_start;
- h__Writer(const Dictionary& d) : AS_02::h__Writer(d), m_KLV_start(0){
+ h__Writer(const Dictionary& d) : AS_02::h__AS02Writer(d), m_KLV_start(0){
memset(m_EssenceUL, 0, SMPTE_UL_LENGTH);
}
- ~h__Writer(){}
+ virtual ~h__Writer(){}
Result_t OpenWrite(const char*, ui32_t HeaderSize);
Result_t SetSourceStream(const ASDCP::PCM::AudioDescriptor&);
// reimplement these functions in AS_02_PCM to support modifications for AS-02
Result_t WriteEKLVPacket(const ASDCP::FrameBuffer& FrameBuf,
const byte_t* EssenceUL, AESEncContext* Ctx, HMACContext* HMAC);
- Result_t WriteMXFFooter();
+ Result_t WriteAS02Footer();
};
{
ui32_t TCFrameRate = ( m_ADesc.EditRate == EditRate_23_98 ) ? 24 : m_ADesc.EditRate.Numerator;
- result = WriteMXFHeader(PCM_PACKAGE_LABEL, UL(m_Dict->ul(MDD_WAVWrapping)),
- SOUND_DEF_LABEL, UL(m_EssenceUL), UL(m_Dict->ul(MDD_SoundDataDef)),
- m_ADesc.EditRate, TCFrameRate, calc_CBR_frame_size(m_Info, m_ADesc));
+ result = WriteAS02Header(PCM_PACKAGE_LABEL, UL(m_Dict->ul(MDD_WAVWrapping)),
+ SOUND_DEF_LABEL, UL(m_EssenceUL), UL(m_Dict->ul(MDD_SoundDataDef)),
+ m_ADesc.EditRate, TCFrameRate, calc_CBR_frame_size(m_Info, m_ADesc));
}
return result;
m_State.Goto_FINAL();
- return WriteMXFFooter();
+ return WriteAS02Footer();
}
// Warning: direct manipulation of MXF structures can interfere
// with the normal operation of the wrapper. Caveat emptor!
//
-ASDCP::MXF::OPAtomHeader&
-AS_02::PCM::MXFWriter::OPAtomHeader()
+ASDCP::MXF::OP1aHeader&
+AS_02::PCM::MXFWriter::OP1aHeader()
{
if ( m_Writer.empty() )
{
- assert(g_OPAtomHeader);
- return *g_OPAtomHeader;
+ assert(g_OP1aHeader);
+ return *g_OP1aHeader;
}
return m_Writer->m_HeaderPart;
// Warning: direct manipulation of MXF structures can interfere
// with the normal operation of the wrapper. Caveat emptor!
//
-/*
-ASDCP::MXF::OPAtomIndexFooter&
-AS_02::PCM::MXFWriter::OPAtomIndexFooter()
+ASDCP::MXF::RIP&
+AS_02::PCM::MXFWriter::RIP()
{
if ( m_Writer.empty() )
{
- assert(g_OPAtomIndexFooter);
- return *g_OPAtomIndexFooter;
+ assert(g_RIP);
+ return *g_RIP;
}
- return m_Writer->m_FooterPart;
+ return m_Writer->m_RIP;
}
-*/
+
// Open the file for writing. The file must not exist. Returns error if
// the operation cannot be completed.
return m_Writer->Finalize();
}
-// standard method of opening an MXF file for read
-Result_t
-AS_02::PCM::MXFReader::h__Reader::OpenMXFRead(const char* filename)
-{
- m_LastPosition = 0;
- AS_02::MXF::OP1aIndexBodyPartion* pCurrentBodyPartIndex = NULL;
- Partition* pPart = NULL;
- ui64_t EssenceStart = 0;
- Result_t result = m_File.OpenRead(filename);
-
- if ( ASDCP_SUCCESS(result) )
- result = m_HeaderPart.InitFromFile(m_File);
-
- if ( ASDCP_SUCCESS(result) )
- {
- ui32_t partition_size = m_HeaderPart.m_RIP.PairArray.size();
-
- if ( partition_size > 3 )
- {
- //for all entry except the first and the last(header&footer)
- Array<RIP::Pair>::iterator r_i = m_HeaderPart.m_RIP.PairArray.begin();
- r_i++;
- ui32_t i=2;
-
- while ( r_i != m_HeaderPart.m_RIP.PairArray.end() && i < partition_size )
- {
- m_File.Seek((*r_i).ByteOffset);
- pPart = new Partition(this->m_Dict);
- result = pPart->InitFromFile(m_File);
-
- // TODO:: expect Index partition
- delete pPart;
- m_File.Seek((*r_i).ByteOffset);
- pCurrentBodyPartIndex = new AS_02::MXF::OP1aIndexBodyPartion(this->m_Dict);
- pCurrentBodyPartIndex->m_Lookup = &m_HeaderPart.m_Primer;
- result = pCurrentBodyPartIndex->InitFromFile(m_File);
-
- if ( ASDCP_FAILURE(result) )
- {
- break;
- }
-
- r_i++; i++;
-
- m_File.Seek((*r_i).ByteOffset);
- pPart = new Partition(this->m_Dict);
- result = pPart->InitFromFile(m_File);
- EssenceStart = m_File.Tell();
-
- if ( ASDCP_FAILURE(result) )
- {
- break;
- }
-
- if(i==3)
- {
- m_EssenceStart = EssenceStart;
- m_pCurrentBodyPartition = pPart;
- m_pCurrentIndexPartition = pCurrentBodyPartIndex;
- }
-
- m_BodyPartList.push_back(pCurrentBodyPartIndex);
- m_BodyPartList.push_back(pPart);
- r_i++; i++;
- }
- }
- }
-
- return result;
-}
-
-// standard method of reading a plaintext or encrypted frame
-Result_t
-AS_02::PCM::MXFReader::h__Reader::ReadEKLVFrame(ui32_t FrameNum, ASDCP::FrameBuffer& FrameBuf,
- const byte_t* EssenceUL, AESDecContext* Ctx, HMACContext* HMAC)
-{
- Result_t result = RESULT_OK;
- // look up frame index node
- IndexTableSegment::IndexEntry TmpEntry;
- ui32_t i = 0;
-
- if(m_pCurrentIndexPartition == NULL)
- {
- m_pCurrentIndexPartition = dynamic_cast<AS_02::MXF::OP1aIndexBodyPartion*> (m_BodyPartList.at(i));
- m_pCurrentBodyPartition = m_BodyPartList.at(i+1);
- }
- else
- {
- return RESULT_FORMAT; //return error
- }
-
- if(m_pCurrentIndexPartition == NULL)
- {
- return RESULT_FORMAT; //return error\r
- }
-
- m_pCurrentIndexPartition->PCMIndexLookup(FrameNum,TmpEntry);
- // get frame position and go read the frame's key and length
- Kumu::fpos_t FilePosition = this->m_EssenceStart + TmpEntry.StreamOffset;
-
- if ( FilePosition != m_LastPosition )
- {
- m_LastPosition = FilePosition;
- result = m_File.Seek(FilePosition);
- }
-
- if( ASDCP_SUCCESS(result) )
- result = ReadEKLVPacket(FrameNum, FrameNum + 1, FrameBuf, EssenceUL, Ctx, HMAC);
-
- return result;
-}
-
-Result_t
-AS_02::PCM::MXFReader::h__Reader::ReadEKLVPacket(ui32_t FrameNum, ui32_t SequenceNum, ASDCP::FrameBuffer& FrameBuf,
- const byte_t* EssenceUL, AESDecContext* Ctx, HMACContext* HMAC)
-{
- KLReader Reader;
-
- //save position to read KLV packet
- Kumu::fpos_t SaveFilePosition = m_File.Tell();
- //Seek backward to KLV start
- m_File.Seek(this->m_EssenceStart);
- Result_t result = Reader.ReadKLFromFile(m_File);
- //set old position
- m_File.Seek(SaveFilePosition);
-
- if ( ASDCP_FAILURE(result) )
- return result;
-
- UL Key(Reader.Key());
- ui64_t PacketLength = Reader.Length();
- m_LastPosition = m_LastPosition + PacketLength;
- if(FrameNum = 0){
- m_LastPosition+= Reader.KLLength();
- }
- assert(m_Dict);
-
- //TODO: for AS_02 PCM - not in the dictionary
-
- static const byte_t WaveClipEssenceUL_Data[SMPTE_UL_LENGTH] =\r
- { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x02, 0x01, 0x01,\r
- 0x0d, 0x01, 0x03, 0x01, 0x16, 0x01, 0x02, 0x01 };
-
- \r
- if( memcmp(Key.Value(), WaveClipEssenceUL_Data, SMPTE_UL_LENGTH) == 0 ){
- byte_t WaveFrameEssenceUL_Data[SMPTE_UL_LENGTH] =\r
- { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x02, 0x01, 0x01,\r
- 0x0d, 0x01, 0x03, 0x01, 0x16, 0x01, 0x01, 0x01 };
-
- Key.Set(WaveFrameEssenceUL_Data);
- }
-
-
- if ( memcmp(Key.Value(), m_Dict->ul(MDD_CryptEssence), Key.Size() - 1) == 0 ) // ignore the stream numbers
- {
- if ( ! m_Info.EncryptedEssence )
- {
- DefaultLogSink().Error("EKLV packet found, no Cryptographic Context in header.\n");
- return RESULT_FORMAT;
- }
-
- // read encrypted triplet value into internal buffer
- assert(PacketLength <= 0xFFFFFFFFL);
- m_CtFrameBuf.Capacity((ui32_t) PacketLength);
- ui32_t read_count;
- result = m_File.Read(m_CtFrameBuf.Data(), (ui32_t) PacketLength,
- &read_count);
-
- if ( ASDCP_FAILURE(result) )
- return result;
-
- if ( read_count != PacketLength )
- {
- DefaultLogSink().Error("read length is smaller than EKLV packet length.\n");
- return RESULT_FORMAT;
- }
-
- m_CtFrameBuf.Size((ui32_t) PacketLength);
-
- // should be const but mxflib::ReadBER is not
- byte_t* ess_p = m_CtFrameBuf.Data();
-
- // read context ID length
- if ( ! Kumu::read_test_BER(&ess_p, UUIDlen) )
- return RESULT_FORMAT;
-
- // test the context ID
- if ( memcmp(ess_p, m_Info.ContextID, UUIDlen) != 0 )
- {
- DefaultLogSink().Error("Packet's Cryptographic Context ID does not match the header.\n");
- return RESULT_FORMAT;
- }
- ess_p += UUIDlen;
-
- // read PlaintextOffset length
- if ( ! Kumu::read_test_BER(&ess_p, sizeof(ui64_t)) )
- return RESULT_FORMAT;
-
- ui32_t PlaintextOffset = (ui32_t)KM_i64_BE(Kumu::cp2i<ui64_t>(ess_p));
- ess_p += sizeof(ui64_t);
-
- // read essence UL length
- if ( ! Kumu::read_test_BER(&ess_p, SMPTE_UL_LENGTH) )
- return RESULT_FORMAT;
-
- // test essence UL
- if ( memcmp(ess_p, EssenceUL, SMPTE_UL_LENGTH - 1) != 0 ) // ignore the stream number
- {
- char strbuf[IntBufferLen];
- const MDDEntry* Entry = m_Dict->FindUL(Key.Value());
- if ( Entry == 0 )
- DefaultLogSink().Warn("Unexpected Essence UL found: %s.\n", Key.EncodeString(strbuf, IntBufferLen));
- else
- DefaultLogSink().Warn("Unexpected Essence UL found: %s.\n", Entry->name);
- return RESULT_FORMAT;
- }
- ess_p += SMPTE_UL_LENGTH;
-
- // read SourceLength length
- if ( ! Kumu::read_test_BER(&ess_p, sizeof(ui64_t)) )
- return RESULT_FORMAT;
-
- ui32_t SourceLength = (ui32_t)KM_i64_BE(Kumu::cp2i<ui64_t>(ess_p));
- ess_p += sizeof(ui64_t);
- assert(SourceLength);
-
- if ( FrameBuf.Capacity() < SourceLength )
- {
- DefaultLogSink().Error("FrameBuf.Capacity: %u SourceLength: %u\n", FrameBuf.Capacity(), SourceLength);
- return RESULT_SMALLBUF;
- }
-
- ui32_t esv_length = calc_esv_length(SourceLength, PlaintextOffset);
-
- // read ESV length
- if ( ! Kumu::read_test_BER(&ess_p, esv_length) )
- {
- DefaultLogSink().Error("read_test_BER did not return %u\n", esv_length);
- return RESULT_FORMAT;
- }
-
- ui32_t tmp_len = esv_length + (m_Info.UsesHMAC ? klv_intpack_size : 0);
-
- if ( PacketLength < tmp_len )
- {
- DefaultLogSink().Error("Frame length is larger than EKLV packet length.\n");
- return RESULT_FORMAT;
- }
-
- if ( Ctx )
- {
- // wrap the pointer and length as a FrameBuffer for use by
- // DecryptFrameBuffer() and TestValues()
- FrameBuffer TmpWrapper;
- TmpWrapper.SetData(ess_p, tmp_len);
- TmpWrapper.Size(tmp_len);
- TmpWrapper.SourceLength(SourceLength);
- TmpWrapper.PlaintextOffset(PlaintextOffset);
-
- result = DecryptFrameBuffer(TmpWrapper, FrameBuf, Ctx);
- FrameBuf.FrameNumber(FrameNum);
-
- // detect and test integrity pack
- if ( ASDCP_SUCCESS(result) && m_Info.UsesHMAC && HMAC )
- {
- IntegrityPack IntPack;
- result = IntPack.TestValues(TmpWrapper, m_Info.AssetUUID, SequenceNum, HMAC);
- }
- }
- else // return ciphertext to caller
- {
- if ( FrameBuf.Capacity() < tmp_len )
- {
- char intbuf[IntBufferLen];
- DefaultLogSink().Error("FrameBuf.Capacity: %u FrameLength: %s\n",
- FrameBuf.Capacity(), ui64sz(PacketLength, intbuf));
- return RESULT_SMALLBUF;
- }
-
- memcpy(FrameBuf.Data(), ess_p, tmp_len);
- FrameBuf.Size(tmp_len);
- FrameBuf.FrameNumber(FrameNum);
- FrameBuf.SourceLength(SourceLength);
- FrameBuf.PlaintextOffset(PlaintextOffset);
- }
- }
- else if ( memcmp(Key.Value(), EssenceUL, Key.Size() - 1) == 0 ) // ignore the stream number
- { // read plaintext frame
- if ( FrameBuf.Capacity() < PacketLength )
- {
- char intbuf[IntBufferLen];
- DefaultLogSink().Error("FrameBuf.Capacity: %u FrameLength: %s\n",
- FrameBuf.Capacity(), ui64sz(PacketLength, intbuf));
- return RESULT_SMALLBUF;
- }
-
- // read the data into the supplied buffer
- ui32_t read_count;
- assert(PacketLength <= 0xFFFFFFFFL);
- result = m_File.Read(FrameBuf.Data(), (ui32_t) PacketLength, &read_count);
-
- if ( ASDCP_FAILURE(result) )
- return result;
-
- if ( read_count != PacketLength )
- {
- char intbuf1[IntBufferLen];
- char intbuf2[IntBufferLen];
- DefaultLogSink().Error("read_count: %s != FrameLength: %s\n",
- ui64sz(read_count, intbuf1),
- ui64sz(PacketLength, intbuf2) );
-
- return RESULT_READFAIL;
- }
-
- FrameBuf.FrameNumber(FrameNum);
- FrameBuf.Size(read_count);
- }
- else
- {
- char strbuf[IntBufferLen];
- const MDDEntry* Entry = m_Dict->FindUL(Key.Value());
- if ( Entry == 0 )
- DefaultLogSink().Warn("Unexpected Essence UL found: %s.\n", Key.EncodeString(strbuf, IntBufferLen));
- else
- DefaultLogSink().Warn("Unexpected Essence UL found: %s.\n", Entry->name);
- return RESULT_FORMAT;
- }
-
- return result;
-}
-
-// standard method of writing the header and footer of a completed MXF file
-//
-Result_t
-AS_02::PCM::MXFWriter::h__Writer::WriteMXFFooter()
-{
- // 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_CurrentIndexBodyPartition->m_FramesWritten = m_FramesWritten;
- m_CurrentIndexBodyPartition->PCMSetIndexParamsCBR(m_CurrentIndexBodyPartition->m_BytesPerEditUnit+24,m_CurrentIndexBodyPartition->m_BytesPerEditUnit);
- CompleteIndexBodyPart();
-
- 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.FooterPartition = here;
-
- assert(m_Dict);
- // re-label the partition
- UL OP1aUL(m_Dict->ul(MDD_OP1a));
- m_HeaderPart.OperationalPattern = OP1aUL;
- m_HeaderPart.m_Preface->OperationalPattern = m_HeaderPart.OperationalPattern;
-
- m_FooterPart.OperationalPattern = m_HeaderPart.OperationalPattern;
- m_FooterPart.EssenceContainers = m_HeaderPart.EssenceContainers;
- m_FooterPart.FooterPartition = here;
- m_FooterPart.ThisPartition = here;
-
- Result_t result = m_FooterPart.WriteToFile(m_File, m_FramesWritten);
-
- if ( ASDCP_SUCCESS(result) )
- result = m_HeaderPart.m_RIP.WriteToFile(m_File);
-
- if ( ASDCP_SUCCESS(result) )
- result = m_File.Seek(0);
-
- if ( ASDCP_SUCCESS(result) )
- result = m_HeaderPart.WriteToFile(m_File, m_HeaderSize);
-
- //update the value of FooterPartition in all Partitions
- std::vector<Partition*>::iterator bl_i = this->m_BodyPartList.begin();
- for (; bl_i != m_BodyPartList.end(); bl_i++ ){
- (*bl_i)->FooterPartition = m_FooterPart.ThisPartition;
- if ( ASDCP_SUCCESS(result) )
- result = m_File.Seek((*bl_i)->ThisPartition);
- if ( ASDCP_SUCCESS(result) ){
- UL BodyUL(m_Dict->ul(MDD_ClosedCompleteBodyPartition));
- result = (*bl_i)->WriteToFile(m_File, BodyUL);
- }
- }
-
- m_File.Close();
- return result;
-}
-
-// standard method of writing a plaintext or encrypted frame
-Result_t
-AS_02::PCM::MXFWriter::h__Writer::WriteEKLVPacket(const ASDCP::FrameBuffer& FrameBuf, const byte_t* EssenceUL,
- AESEncContext* Ctx, HMACContext* HMAC)
-{
- Result_t result = RESULT_OK;
- IntegrityPack IntPack;
-
- const ui32_t AS_02_PCM_MXF_BER_LENGTH = 8;
- //TODO: AS_02_PCM_MXF_BER_LENGTH - customize for EncryptedEssence
-
- byte_t overhead[128];
- Kumu::MemIOWriter Overhead(overhead, 128);
- assert(m_Dict);
-
- if ( FrameBuf.Size() == 0 )
- {
- DefaultLogSink().Error("Cannot write empty frame buffer\n");
- return RESULT_EMPTY_FB;
- }
-
- if ( m_Info.EncryptedEssence )
- {
- if ( ! Ctx )
- return RESULT_CRYPT_CTX;
-
- if ( m_Info.UsesHMAC && ! HMAC )
- return RESULT_HMAC_CTX;
-
- if ( FrameBuf.PlaintextOffset() > FrameBuf.Size() )
- return RESULT_LARGE_PTO;
-
- // encrypt the essence data (create encrypted source value)
- result = EncryptFrameBuffer(FrameBuf, m_CtFrameBuf, Ctx);
-
- // create HMAC
- if ( ASDCP_SUCCESS(result) && m_Info.UsesHMAC )
- result = IntPack.CalcValues(m_CtFrameBuf, m_Info.AssetUUID, m_FramesWritten + 1, HMAC);
-
- if ( ASDCP_SUCCESS(result) )
- { // write UL
- Overhead.WriteRaw(m_Dict->ul(MDD_CryptEssence), SMPTE_UL_LENGTH);
-
- // construct encrypted triplet header
- ui32_t ETLength = klv_cryptinfo_size + m_CtFrameBuf.Size();
- ui32_t BER_length = MXF_BER_LENGTH;
-
- if ( m_Info.UsesHMAC )
- ETLength += klv_intpack_size;
- else
- ETLength += (MXF_BER_LENGTH * 3); // for empty intpack
-
- if ( ETLength > 0x00ffffff ) // Need BER integer longer than MXF_BER_LENGTH bytes
- {
- BER_length = Kumu::get_BER_length_for_value(ETLength);
-
- // the packet is longer by the difference in expected vs. actual BER length
- ETLength += BER_length - MXF_BER_LENGTH;
-
- if ( BER_length == 0 )
- result = RESULT_KLV_CODING;
- }
-
- if ( ASDCP_SUCCESS(result) )
- {
- if ( ! ( Overhead.WriteBER(ETLength, BER_length) // write encrypted triplet length
- && Overhead.WriteBER(UUIDlen, MXF_BER_LENGTH) // write ContextID length
- && Overhead.WriteRaw(m_Info.ContextID, UUIDlen) // write ContextID
- && Overhead.WriteBER(sizeof(ui64_t), MXF_BER_LENGTH) // write PlaintextOffset length
- && Overhead.WriteUi64BE(FrameBuf.PlaintextOffset()) // write PlaintextOffset
- && Overhead.WriteBER(SMPTE_UL_LENGTH, MXF_BER_LENGTH) // write essence UL length
- && Overhead.WriteRaw((byte_t*)EssenceUL, SMPTE_UL_LENGTH) // write the essence UL
- && Overhead.WriteBER(sizeof(ui64_t), MXF_BER_LENGTH) // write SourceLength length
- && Overhead.WriteUi64BE(FrameBuf.Size()) // write SourceLength
- && Overhead.WriteBER(m_CtFrameBuf.Size(), BER_length) ) ) // write ESV length
- {
- result = RESULT_KLV_CODING;
- }
- }
-
- if ( ASDCP_SUCCESS(result) )
- result = m_File.Writev(Overhead.Data(), Overhead.Length());
- }
-
- if ( ASDCP_SUCCESS(result) )
- {
- m_StreamOffset += Overhead.Length();
- // write encrypted source value
- result = m_File.Writev((byte_t*)m_CtFrameBuf.RoData(), m_CtFrameBuf.Size());
- }
-
- if ( ASDCP_SUCCESS(result) )
- {
- m_StreamOffset += m_CtFrameBuf.Size();
-
- byte_t hmoverhead[512];
- Kumu::MemIOWriter HMACOverhead(hmoverhead, 512);
-
- // write the HMAC
- if ( m_Info.UsesHMAC )
- {
- HMACOverhead.WriteRaw(IntPack.Data, klv_intpack_size);
- }
- else
- { // we still need the var-pack length values if the intpack is empty
- for ( ui32_t i = 0; i < 3 ; i++ )
- HMACOverhead.WriteBER(0, MXF_BER_LENGTH);
- }
-
- // write HMAC
- result = m_File.Writev(HMACOverhead.Data(), HMACOverhead.Length());
- m_StreamOffset += HMACOverhead.Length();
- }
- }
- else
- {
- if(m_FramesWritten == 0){
- ui32_t BER_length = AS_02_PCM_MXF_BER_LENGTH; //MXF_BER_LENGTH;
-
- if ( FrameBuf.Size() > 0x00ffffff ) // Need BER integer longer than MXF_BER_LENGTH bytes
- {
- BER_length = Kumu::get_BER_length_for_value(FrameBuf.Size());
-
- if ( BER_length == 0 )
- result = RESULT_KLV_CODING;
- }
-
- Overhead.WriteRaw((byte_t*)EssenceUL, SMPTE_UL_LENGTH);
- Overhead.WriteBER(FrameBuf.Size(), BER_length);
-
- //position of the KLV start
- m_KLV_start = m_File.Tell();
-
- if ( ASDCP_SUCCESS(result) )
- result = m_File.Writev(Overhead.Data(), Overhead.Length());
- if ( ASDCP_SUCCESS(result) )
- result = m_File.Writev((byte_t*)FrameBuf.RoData(), FrameBuf.Size());
-
- if ( ASDCP_SUCCESS(result) )
- m_StreamOffset += Overhead.Length() + FrameBuf.Size();
- }
- else{
- //update the KLV - length; new value plus old value from length field
- //necessary to know position of length field -> bodyPartition + 8
- //update every time when writing new essence or at the end of writing
-
- if ( ASDCP_SUCCESS(result) )
- result = m_File.Writev((byte_t*)FrameBuf.RoData(), FrameBuf.Size());
-
- if ( ASDCP_SUCCESS(result) )
- m_StreamOffset += FrameBuf.Size();
- }
- }
-
- if ( ASDCP_SUCCESS(result) )
- result = m_File.Writev();
-
- return result;
-}
//
// end AS_02_PCM.cpp
/*
- Copyright (c) 2011-2012, Robert Scheler, Heiko Sparenberg Fraunhofer IIS, John Hurst
+ Copyright (c) 2011-2013, Robert Scheler, Heiko Sparenberg Fraunhofer IIS, John Hurst
All rights reserved.
Redistribution and use in source and binary forms, with or without
#ifndef _AS_02_INTERNAL_H_
#define _AS_02_INTERNAL_H_
-#include "KM_platform.h"
-#include "KM_util.h"
#include "KM_log.h"
-#include "Metadata.h"
#include "AS_DCP_internal.h"
#include "AS_02.h"
using Kumu::DefaultLogSink;
-using namespace ASDCP;
-using namespace ASDCP::MXF;
+#ifdef DEFAULT_MD_DECL
+AS_02::MXF::AS02IndexReader *g_AS02IndexReader;
+#else
+extern AS_02::MXF::AS02IndexReader *g_AS02IndexReader;
+#endif
+
namespace AS_02
{
+
+ void default_md_object_init();
+
static void CalculateIndexPartitionSize(ui32_t& size,ui32_t numberOfIndexEntries)
{
if(numberOfIndexEntries){
}
//
- class h__Reader
- {
- ASDCP_NO_COPY_CONSTRUCT(h__Reader);
- h__Reader();
-
- public:
- const Dictionary* m_Dict;
- Kumu::FileReader m_File;
- OPAtomHeader m_HeaderPart;
- //more than one Body-Partition use a list
- std::vector<Partition*> m_BodyPartList;
- OPAtomIndexFooter m_FooterPart;
- ui64_t m_EssenceStart;
- WriterInfo m_Info;
- ASDCP::FrameBuffer m_CtFrameBuf;
- Kumu::fpos_t m_LastPosition;
-
- IndexStrategy_t m_IndexStrategy; //Shim parameter index_strategy_frame/clip
- ui32_t m_PartitionSpace;
-
- ////new elements for AS-02
- Partition* m_pCurrentBodyPartition;
- AS_02::MXF::OP1aIndexBodyPartion* m_pCurrentIndexPartition;
- ui32_t m_start_pos;
-
- h__Reader(const Dictionary&);
- virtual ~h__Reader();
-
- Result_t InitInfo();
- virtual Result_t OpenMXFRead(const char* filename) = 0;
- Result_t InitMXFIndex();
-
- // positions file before reading
- virtual Result_t ReadEKLVFrame(ui32_t FrameNum, ASDCP::FrameBuffer& FrameBuf,
- const byte_t* EssenceUL, AESDecContext* Ctx, HMACContext* HMAC) = 0;
-
- // reads from current position
- virtual Result_t ReadEKLVPacket(ui32_t FrameNum, ui32_t SequenceNum, ASDCP::FrameBuffer& FrameBuf,
- const byte_t* EssenceUL, AESDecContext* Ctx, HMACContext* HMAC) = 0;
- void Close();
- };
+ class h__AS02Reader : public ASDCP::MXF::TrackFileReader<ASDCP::MXF::OP1aHeader, AS_02::MXF::AS02IndexReader>
+ {
+ ASDCP_NO_COPY_CONSTRUCT(h__AS02Reader);
+ h__AS02Reader();
+
+ public:
+ Partition *m_pCurrentBodyPartition;
+ AS_02::MXF::OP1aIndexBodyPartion* m_pCurrentIndexPartition;
+ ui64_t m_EssenceStart;
+ std::vector<Partition*> m_BodyPartList;
+ ui32_t m_start_pos;
+ ui32_t m_PartitionSpace;
+ IndexStrategy_t m_IndexStrategy; //Shim parameter index_strategy_frame/clip
+
+ h__AS02Reader(const ASDCP::Dictionary&);
+ virtual ~h__AS02Reader();
+
+ Result_t OpenMXFRead(const char* filename);
+ Result_t ReadEKLVFrame(ui32_t FrameNum, ASDCP::FrameBuffer& FrameBuf,
+ const byte_t* EssenceUL, ASDCP::AESDecContext* Ctx, ASDCP::HMACContext* HMAC);
+ Result_t LocateFrame(ui32_t FrameNum, Kumu::fpos_t& streamOffset,
+ i8_t& temporalOffset, i8_t& keyFrameOffset);
+
+ };
//
- class h__Writer
- {
- ASDCP_NO_COPY_CONSTRUCT(h__Writer);
- h__Writer();
-
- public:
- const Dictionary* m_Dict;
- Kumu::FileWriter m_File;
- ui32_t m_HeaderSize;
- OPAtomHeader m_HeaderPart;
- //more than one Body-Partition -> use a list of Partitions
- std::vector<Partition*> m_BodyPartList;
- //we don't use the footer like in the dcps but we need also a footer
- AS_02::MXF::OP1aIndexFooter m_FooterPart;
- ui64_t m_EssenceStart;
-
- MaterialPackage* m_MaterialPackage;
- SourcePackage* m_FilePackage;
-
- FileDescriptor* m_EssenceDescriptor;
- std::list<InterchangeObject*> m_EssenceSubDescriptorList;
-
- ui32_t m_FramesWritten;
- ui64_t m_StreamOffset;
- ASDCP::FrameBuffer m_CtFrameBuf;
- h__WriterState m_State;
- WriterInfo m_Info;
- DurationElementList_t m_DurationUpdateList;
-
- //new elements for AS-02
- ui64_t m_BodyOffset;
- //TODO: Currently not used, delete if not necessary
- // Counter values for BodySID and IndexSID
- ui32_t m_CurrentBodySID;
- ui32_t m_CurrentIndexSID;
- //TODO: maybe set this to the lf__Writer class because this is only in JP2K creation necessary
- //our computed PartitionSpace
- ui32_t m_PartitionSpace;
- IndexStrategy_t m_IndexStrategy; //Shim parameter index_strategy_frame/clip
-
- //the EditRate
- ASDCP::MXF::Rational m_EditRate;
- //the BytesPerEditUnit
- ui32_t m_BytesPerEditUnit;
- //pointer to the current Body Partition(Index)
- AS_02::MXF::OP1aIndexBodyPartion* m_CurrentIndexBodyPartition;
-
- h__Writer(const Dictionary&);
- virtual ~h__Writer();
-
- //virtual methods, implementation details for JP2K or PCM are in the MXFWriter::h__Writer classes if they are different
- virtual void InitHeader();
- /*virtual*/ void AddSourceClip(const ASDCP::MXF::Rational& EditRate, ui32_t TCFrameRate,
- const std::string& TrackName, const UL& EssenceUL,
- const UL& DataDefinition, const std::string& PackageLabel);
- /*virtual*/ void AddDMSegment(const ASDCP::MXF::Rational& EditRate, ui32_t TCFrameRate,
- const std::string& TrackName, const UL& DataDefinition,
- const std::string& PackageLabel);
- /*virtual*/ void AddEssenceDescriptor(const ASDCP::UL& WrappingUL);
- virtual Result_t CreateBodyPart(const ASDCP::MXF::Rational& EditRate, ui32_t BytesPerEditUnit = 0);
-
- //new method to create BodyPartition for essence and index
- virtual Result_t CreateBodyPartPair();
- //new method to finalize BodyPartion(index)
- virtual Result_t CompleteIndexBodyPart();
-
- // all the above for a single source clip
- virtual Result_t WriteMXFHeader(const std::string& PackageLabel, const UL& WrappingUL,
- const std::string& TrackName, const UL& EssenceUL,
- const UL& DataDefinition, const ASDCP::MXF::Rational& EditRate,
- ui32_t TCFrameRate, ui32_t BytesPerEditUnit = 0);
-
- virtual Result_t WriteEKLVPacket(const ASDCP::FrameBuffer& FrameBuf,
- const byte_t* EssenceUL, AESEncContext* Ctx, HMACContext* HMAC);
-
- virtual Result_t WriteMXFFooter() = 0;
-
- };
+ class h__AS02Writer : public ASDCP::MXF::TrackFileWriter<ASDCP::MXF::OP1aHeader>
+ {
+ ASDCP_NO_COPY_CONSTRUCT(h__AS02Writer);
+ h__AS02Writer();
+
+ public:
+ AS_02::MXF::OP1aIndexBodyPartion* m_CurrentIndexBodyPartition;
+ ui64_t m_BodyOffset;
+ ui32_t m_PartitionSpace;
+ IndexStrategy_t m_IndexStrategy; //Shim parameter index_strategy_frame/clip
+ std::vector<Partition*> m_BodyPartList;
+
+ h__AS02Writer(const Dictionary&);
+ virtual ~h__AS02Writer();
+
+ // all the above for a single source clip
+ Result_t WriteAS02Header(const std::string& PackageLabel, const ASDCP::UL& WrappingUL,
+ const std::string& TrackName, const ASDCP::UL& EssenceUL,
+ const ASDCP::UL& DataDefinition, const ASDCP::Rational& EditRate,
+ ui32_t TCFrameRate, ui32_t BytesPerEditUnit = 0);
+
+ Result_t CreateBodyPart(const ASDCP::MXF::Rational& EditRate, ui32_t BytesPerEditUnit);
+ Result_t CreateBodyPartPair();
+ Result_t CompleteIndexBodyPart();
+
+ Result_t WriteAS02Footer();
+ };
} // namespace AS_02
namespace MXF {
// #include<Metadata.h> to use these
- class OPAtomHeader;
+ class OP1aHeader;
class OPAtomIndexFooter;
+ class RIP;
};
//---------------------------------------------------------------------------------
// Warning: direct manipulation of MXF structures can interfere
// with the normal operation of the wrapper. Caveat emptor!
- virtual MXF::OPAtomHeader& OPAtomHeader();
+ virtual MXF::OP1aHeader& OP1aHeader();
virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
+ virtual MXF::RIP& RIP();
// Open the file for writing. The file must not exist. Returns error if
// the operation cannot be completed or if nonsensical data is discovered
// Warning: direct manipulation of MXF structures can interfere
// with the normal operation of the wrapper. Caveat emptor!
- virtual MXF::OPAtomHeader& OPAtomHeader();
+ virtual MXF::OP1aHeader& OP1aHeader();
virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
+ virtual MXF::RIP& RIP();
// Open the file for reading. The file must exist. Returns error if the
// operation cannot be completed.
// Warning: direct manipulation of MXF structures can interfere
// with the normal operation of the wrapper. Caveat emptor!
- virtual MXF::OPAtomHeader& OPAtomHeader();
+ virtual MXF::OP1aHeader& OP1aHeader();
virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
+ virtual MXF::RIP& RIP();
// Open the file for writing. The file must not exist. Returns error if
// the operation cannot be completed or if nonsensical data is discovered
// Warning: direct manipulation of MXF structures can interfere
// with the normal operation of the wrapper. Caveat emptor!
- virtual MXF::OPAtomHeader& OPAtomHeader();
+ virtual MXF::OP1aHeader& OP1aHeader();
virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
+ virtual MXF::RIP& RIP();
// Open the file for reading. The file must exist. Returns error if the
// operation cannot be completed.
// Warning: direct manipulation of MXF structures can interfere
// with the normal operation of the wrapper. Caveat emptor!
- virtual MXF::OPAtomHeader& OPAtomHeader();
+ virtual MXF::OP1aHeader& OP1aHeader();
virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
+ virtual MXF::RIP& RIP();
// Open the file for writing. The file must not exist. Returns error if
// the operation cannot be completed or if nonsensical data is discovered
// Warning: direct manipulation of MXF structures can interfere
// with the normal operation of the wrapper. Caveat emptor!
- virtual MXF::OPAtomHeader& OPAtomHeader();
+ virtual MXF::OP1aHeader& OP1aHeader();
virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
+ virtual MXF::RIP& RIP();
// Open the file for reading. The file must exist. Returns error if the
// operation cannot be completed.
// Warning: direct manipulation of MXF structures can interfere
// with the normal operation of the wrapper. Caveat emptor!
- virtual MXF::OPAtomHeader& OPAtomHeader();
+ virtual MXF::OP1aHeader& OP1aHeader();
virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
+ virtual MXF::RIP& RIP();
// Open the file for writing. The file must not exist. Returns error if
// the operation cannot be completed or if nonsensical data is discovered
// Warning: direct manipulation of MXF structures can interfere
// with the normal operation of the wrapper. Caveat emptor!
- virtual MXF::OPAtomHeader& OPAtomHeader();
+ virtual MXF::OP1aHeader& OP1aHeader();
virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
+ virtual MXF::RIP& RIP();
// Open the file for reading. The file must exist. Returns error if the
// operation cannot be completed.
// Warning: direct manipulation of MXF structures can interfere
// with the normal operation of the wrapper. Caveat emptor!
- virtual MXF::OPAtomHeader& OPAtomHeader();
+ virtual MXF::OP1aHeader& OP1aHeader();
virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
+ virtual MXF::RIP& RIP();
// Open the file for writing. The file must not exist. Returns error if
// the operation cannot be completed or if nonsensical data is discovered
// Warning: direct manipulation of MXF structures can interfere
// with the normal operation of the wrapper. Caveat emptor!
- virtual MXF::OPAtomHeader& OPAtomHeader();
+ virtual MXF::OP1aHeader& OP1aHeader();
virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
+ virtual MXF::RIP& RIP();
// Open the file for reading. The file must exist. Returns error if the
// operation cannot be completed.
// Warning: direct manipulation of MXF structures can interfere
// with the normal operation of the wrapper. Caveat emptor!
- virtual MXF::OPAtomHeader& OPAtomHeader();
+ virtual MXF::OP1aHeader& OP1aHeader();
virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
+ virtual MXF::RIP& RIP();
// Open the file for writing. The file must not exist. Returns error if
// the operation cannot be completed or if nonsensical data is discovered
// Warning: direct manipulation of MXF structures can interfere
// with the normal operation of the wrapper. Caveat emptor!
- virtual MXF::OPAtomHeader& OPAtomHeader();
+ virtual MXF::OP1aHeader& OP1aHeader();
virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
+ virtual MXF::RIP& RIP();
// Open the file for reading. The file must exist. Returns error if the
// operation cannot be completed.
// Warning: direct manipulation of MXF structures can interfere
// with the normal operation of the wrapper. Caveat emptor!
- virtual MXF::OPAtomHeader& OPAtomHeader();
+ virtual MXF::OP1aHeader& OP1aHeader();
virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
+ virtual MXF::RIP& RIP();
// Open the file for writing. The file must not exist. Returns error if
// the operation cannot be completed or if nonsensical data is discovered
// Warning: direct manipulation of MXF structures can interfere
// with the normal operation of the wrapper. Caveat emptor!
- virtual MXF::OPAtomHeader& OPAtomHeader();
+ virtual MXF::OP1aHeader& OP1aHeader();
virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
+ virtual MXF::RIP& RIP();
// Open the file for reading. The file must exist. Returns error if the
// operation cannot be completed.
{
namespace ATMOS
{
- static std::string ATMOS_PACKAGE_LABEL = "File Package: SMPTE 382M frame wrapping of Dolby ATMOS data";
+ static std::string ATMOS_PACKAGE_LABEL = "File Package: SMPTE-GC frame wrapping of Dolby ATMOS data";
static std::string ATMOS_DEF_LABEL = "Dolby ATMOS Data Track";
static byte_t ATMOS_ESSENCE_CODING[SMPTE_UL_LENGTH] = { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x05,
0x0e, 0x09, 0x06, 0x04, 0x00, 0x00, 0x00, 0x00 };
h__Reader(const Dictionary& d) : DCData::h__Reader(d), m_EssenceSubDescriptor(NULL),
m_ADesc() {}
- ~h__Reader() {}
+ virtual ~h__Reader() {}
Result_t OpenRead(const char*);
Result_t MD_to_Atmos_ADesc(ATMOS::AtmosDescriptor& ADesc);
};
// Warning: direct manipulation of MXF structures can interfere
// with the normal operation of the wrapper. Caveat emptor!
//
-ASDCP::MXF::OPAtomHeader&
-ASDCP::ATMOS::MXFReader::OPAtomHeader()
+ASDCP::MXF::OP1aHeader&
+ASDCP::ATMOS::MXFReader::OP1aHeader()
{
if ( m_Reader.empty() )
{
- assert(g_OPAtomHeader);
- return *g_OPAtomHeader;
+ assert(g_OP1aHeader);
+ return *g_OP1aHeader;
}
return m_Reader->m_HeaderPart;
return *g_OPAtomIndexFooter;
}
- return m_Reader->m_FooterPart;
+ return m_Reader->m_IndexAccess;
+}
+
+// Warning: direct manipulation of MXF structures can interfere
+// with the normal operation of the wrapper. Caveat emptor!
+//
+ASDCP::MXF::RIP&
+ASDCP::ATMOS::MXFReader::RIP()
+{
+ if ( m_Reader.empty() )
+ {
+ assert(g_RIP);
+ return *g_RIP;
+ }
+
+ return m_Reader->m_RIP;
}
// Open the file for reading. The file must exist. Returns error if the
ASDCP::ATMOS::MXFReader::DumpIndex(FILE* stream) const
{
if ( m_Reader->m_File.IsOpen() )
- m_Reader->m_FooterPart.Dump(stream);
+ m_Reader->m_IndexAccess.Dump(stream);
}
//
h__Writer(const Dictionary& d) : DCData::h__Writer(d),
m_EssenceSubDescriptor(NULL), m_ADesc() {}
- ~h__Writer(){}
+ virtual ~h__Writer(){}
Result_t OpenWrite(const char*, ui32_t HeaderSize, const AtmosDescriptor& ADesc);
Result_t Atmos_ADesc_to_MD(const AtmosDescriptor& ADesc);
// Warning: direct manipulation of MXF structures can interfere
// with the normal operation of the wrapper. Caveat emptor!
//
-ASDCP::MXF::OPAtomHeader&
-ASDCP::ATMOS::MXFWriter::OPAtomHeader()
+ASDCP::MXF::OP1aHeader&
+ASDCP::ATMOS::MXFWriter::OP1aHeader()
{
if ( m_Writer.empty() )
{
- assert(g_OPAtomHeader);
- return *g_OPAtomHeader;
+ assert(g_OP1aHeader);
+ return *g_OP1aHeader;
}
return m_Writer->m_HeaderPart;
return m_Writer->m_FooterPart;
}
+// Warning: direct manipulation of MXF structures can interfere
+// with the normal operation of the wrapper. Caveat emptor!
+//
+ASDCP::MXF::RIP&
+ASDCP::ATMOS::MXFWriter::RIP()
+{
+ if ( m_Writer.empty() )
+ {
+ assert(g_RIP);
+ return *g_RIP;
+ }
+
+ return m_Writer->m_RIP;
+}
+
// Open the file for writing. The file must not exist. Returns error if
// the operation cannot be completed.
ASDCP::Result_t
{
namespace DCData
{
- static std::string DC_DATA_PACKAGE_LABEL = "File Package: SMPTE 382M frame wrapping of D-Cinema Generic data";
+ static std::string DC_DATA_PACKAGE_LABEL = "File Package: SMPTE-GC frame wrapping of D-Cinema Generic data";
static std::string DC_DATA_DEF_LABEL = "D-Cinema Generic Data Track";
} // namespace DCData
} // namespace ASDCP
return RESULT_FORMAT;
}
- if( ASDCP_SUCCESS(result) )
- result = InitMXFIndex();
-
- if( ASDCP_SUCCESS(result) )
- result = InitInfo();
-
return result;
}
public:
h__Reader(const Dictionary& d) : DCData::h__Reader(d) {}
+ virtual ~h__Reader() {}
};
// Warning: direct manipulation of MXF structures can interfere
// with the normal operation of the wrapper. Caveat emptor!
//
-ASDCP::MXF::OPAtomHeader&
-ASDCP::DCData::MXFReader::OPAtomHeader()
+ASDCP::MXF::OP1aHeader&
+ASDCP::DCData::MXFReader::OP1aHeader()
{
if ( m_Reader.empty() )
{
- assert(g_OPAtomHeader);
- return *g_OPAtomHeader;
+ assert(g_OP1aHeader);
+ return *g_OP1aHeader;
}
return m_Reader->m_HeaderPart;
return *g_OPAtomIndexFooter;
}
- return m_Reader->m_FooterPart;
+ return m_Reader->m_IndexAccess;
+}
+
+// Warning: direct manipulation of MXF structures can interfere
+// with the normal operation of the wrapper. Caveat emptor!
+//
+ASDCP::MXF::RIP&
+ASDCP::DCData::MXFReader::RIP()
+{
+ if ( m_Reader.empty() )
+ {
+ assert(g_RIP);
+ return *g_RIP;
+ }
+
+ return m_Reader->m_RIP;
}
// Open the file for reading. The file must exist. Returns error if the
ASDCP::DCData::MXFReader::DumpIndex(FILE* stream) const
{
if ( m_Reader->m_File.IsOpen() )
- m_Reader->m_FooterPart.Dump(stream);
+ m_Reader->m_IndexAccess.Dump(stream);
}
//
{
ui32_t TCFrameRate = m_DDesc.EditRate.Numerator;
- result = WriteMXFHeader(packageLabel, UL(m_Dict->ul(MDD_DCDataWrapping)),
- defLabel, UL(m_EssenceUL), UL(m_Dict->ul(MDD_DataDataDef)),
- m_DDesc.EditRate, TCFrameRate);
+ result = WriteASDCPHeader(packageLabel, UL(m_Dict->ul(MDD_DCDataWrapping)),
+ defLabel, UL(m_EssenceUL), UL(m_Dict->ul(MDD_DataDataDef)),
+ m_DDesc.EditRate, TCFrameRate);
}
return result;
m_State.Goto_FINAL();
- return WriteMXFFooter();
+ return WriteASDCPFooter();
}
public:
h__Writer(const Dictionary& d) : DCData::h__Writer(d) {}
+ virtual ~h__Writer() {}
};
// Warning: direct manipulation of MXF structures can interfere
// with the normal operation of the wrapper. Caveat emptor!
//
-ASDCP::MXF::OPAtomHeader&
-ASDCP::DCData::MXFWriter::OPAtomHeader()
+ASDCP::MXF::OP1aHeader&
+ASDCP::DCData::MXFWriter::OP1aHeader()
{
if ( m_Writer.empty() )
{
- assert(g_OPAtomHeader);
- return *g_OPAtomHeader;
+ assert(g_OP1aHeader);
+ return *g_OP1aHeader;
}
return m_Writer->m_HeaderPart;
return m_Writer->m_FooterPart;
}
+// Warning: direct manipulation of MXF structures can interfere
+// with the normal operation of the wrapper. Caveat emptor!
+//
+ASDCP::MXF::RIP&
+ASDCP::DCData::MXFWriter::RIP()
+{
+ if ( m_Writer.empty() )
+ {
+ assert(g_RIP);
+ return *g_RIP;
+ }
+
+ return m_Writer->m_RIP;
+}
+
// Open the file for writing. The file must not exist. Returns error if
// the operation cannot be completed.
ASDCP::Result_t
/*
-Copyright (c) 2004-2012, John Hurst
+Copyright (c) 2004-2013, John Hurst
All rights reserved.
Redistribution and use in source and binary forms, with or without
Result_t MD_to_DCData_DDesc(DCData::DCDataDescriptor& DDesc);
};
- class h__Writer : public ASDCP::h__Writer
+ class h__Writer : public ASDCP::h__ASDCPWriter
{
ASDCP_NO_COPY_CONSTRUCT(h__Writer);
h__Writer();
DCDataDescriptor m_DDesc;
byte_t m_EssenceUL[SMPTE_UL_LENGTH];
- h__Writer(const Dictionary& d) : ASDCP::h__Writer(d) {
+ h__Writer(const Dictionary& d) : ASDCP::h__ASDCPWriter(d) {
memset(m_EssenceUL, 0, SMPTE_UL_LENGTH);
}
/*
-Copyright (c) 2004-2012, John Hurst
+Copyright (c) 2004-2013, John Hurst
All rights reserved.
Redistribution and use in source and binary forms, with or without
lh__Reader(const Dictionary& d) :
ASDCP::h__ASDCPReader(d), m_EssenceDescriptor(0), m_EssenceSubDescriptor(0), m_Format(ESS_UNKNOWN) {}
+
+ virtual ~lh__Reader() {}
+
Result_t OpenRead(const char*, EssenceType_t);
Result_t ReadFrame(ui32_t, JP2K::FrameBuffer&, AESDecContext*, HMACContext*);
Result_t MD_to_JP2K_PDesc(JP2K::PictureDescriptor& PDesc);
result = MD_to_JP2K_PDesc(m_PDesc);
}
- if( ASDCP_SUCCESS(result) )
- result = InitMXFIndex();
-
- if( ASDCP_SUCCESS(result) )
- result = InitInfo();
-
return result;
}
// Warning: direct manipulation of MXF structures can interfere
// with the normal operation of the wrapper. Caveat emptor!
//
-ASDCP::MXF::OPAtomHeader&
-ASDCP::JP2K::MXFReader::OPAtomHeader()
+ASDCP::MXF::OP1aHeader&
+ASDCP::JP2K::MXFReader::OP1aHeader()
{
if ( m_Reader.empty() )
{
- assert(g_OPAtomHeader);
- return *g_OPAtomHeader;
+ assert(g_OP1aHeader);
+ return *g_OP1aHeader;
}
return m_Reader->m_HeaderPart;
return *g_OPAtomIndexFooter;
}
- return m_Reader->m_FooterPart;
+ return m_Reader->m_IndexAccess;
+}
+
+// Warning: direct manipulation of MXF structures can interfere
+// with the normal operation of the wrapper. Caveat emptor!
+//
+ASDCP::MXF::RIP&
+ASDCP::JP2K::MXFReader::RIP()
+{
+ if ( m_Reader.empty() )
+ {
+ assert(g_RIP);
+ return *g_RIP;
+ }
+
+ return m_Reader->m_RIP;
}
// Open the file for reading. The file must exist. Returns error if the
ASDCP::JP2K::MXFReader::DumpIndex(FILE* stream) const
{
if ( m_Reader->m_File.IsOpen() )
- m_Reader->m_FooterPart.Dump(stream);
+ m_Reader->m_IndexAccess.Dump(stream);
}
//
// look up frame index node
IndexTableSegment::IndexEntry TmpEntry;
- if ( ASDCP_FAILURE(m_FooterPart.Lookup(FrameNum, TmpEntry)) )
+ if ( ASDCP_FAILURE(m_IndexAccess.Lookup(FrameNum, TmpEntry)) )
{
DefaultLogSink().Error("Frame value out of range: %u\n", FrameNum);
return RESULT_RANGE;
// Warning: direct manipulation of MXF structures can interfere
// with the normal operation of the wrapper. Caveat emptor!
//
-ASDCP::MXF::OPAtomHeader&
-ASDCP::JP2K::MXFSReader::OPAtomHeader()
+ASDCP::MXF::OP1aHeader&
+ASDCP::JP2K::MXFSReader::OP1aHeader()
{
if ( m_Reader.empty() )
{
- assert(g_OPAtomHeader);
- return *g_OPAtomHeader;
+ assert(g_OP1aHeader);
+ return *g_OP1aHeader;
}
return m_Reader->m_HeaderPart;
return *g_OPAtomIndexFooter;
}
- return m_Reader->m_FooterPart;
+ return m_Reader->m_IndexAccess;
+}
+
+// Warning: direct manipulation of MXF structures can interfere
+// with the normal operation of the wrapper. Caveat emptor!
+//
+ASDCP::MXF::RIP&
+ASDCP::JP2K::MXFSReader::RIP()
+{
+ if ( m_Reader.empty() )
+ {
+ assert(g_RIP);
+ return *g_RIP;
+ }
+
+ return m_Reader->m_RIP;
}
// Open the file for reading. The file must exist. Returns error if the
ASDCP::JP2K::MXFSReader::DumpIndex(FILE* stream) const
{
if ( m_Reader->m_File.IsOpen() )
- m_Reader->m_FooterPart.Dump(stream);
+ m_Reader->m_IndexAccess.Dump(stream);
}
//
//
-class lh__Writer : public ASDCP::h__Writer
+class lh__Writer : public ASDCP::h__ASDCPWriter
{
ASDCP_NO_COPY_CONSTRUCT(lh__Writer);
lh__Writer();
PictureDescriptor m_PDesc;
byte_t m_EssenceUL[SMPTE_UL_LENGTH];
- lh__Writer(const Dictionary& d) : ASDCP::h__Writer(d), m_EssenceSubDescriptor(0) {
+ lh__Writer(const Dictionary& d) : ASDCP::h__ASDCPWriter(d), m_EssenceSubDescriptor(0) {
memset(m_EssenceUL, 0, SMPTE_UL_LENGTH);
}
- ~lh__Writer(){}
+ virtual ~lh__Writer(){}
Result_t OpenWrite(const char*, EssenceType_t type, ui32_t HeaderSize);
Result_t SetSourceStream(const PictureDescriptor&, const std::string& label,
{
ui32_t TCFrameRate = ( m_PDesc.EditRate == EditRate_23_98 ) ? 24 : m_PDesc.EditRate.Numerator;
- result = WriteMXFHeader(label, UL(m_Dict->ul(MDD_JPEG_2000Wrapping)),
- PICT_DEF_LABEL, UL(m_EssenceUL), UL(m_Dict->ul(MDD_PictureDataDef)),
- LocalEditRate, TCFrameRate);
+ result = WriteASDCPHeader(label, UL(m_Dict->ul(MDD_JPEG_2000Wrapping)),
+ PICT_DEF_LABEL, UL(m_EssenceUL), UL(m_Dict->ul(MDD_PictureDataDef)),
+ LocalEditRate, TCFrameRate);
}
return result;
m_State.Goto_FINAL();
- return WriteMXFFooter();
+ return WriteASDCPFooter();
}
// Warning: direct manipulation of MXF structures can interfere
// with the normal operation of the wrapper. Caveat emptor!
//
-ASDCP::MXF::OPAtomHeader&
-ASDCP::JP2K::MXFWriter::OPAtomHeader()
+ASDCP::MXF::OP1aHeader&
+ASDCP::JP2K::MXFWriter::OP1aHeader()
{
if ( m_Writer.empty() )
{
- assert(g_OPAtomHeader);
- return *g_OPAtomHeader;
+ assert(g_OP1aHeader);
+ return *g_OP1aHeader;
}
return m_Writer->m_HeaderPart;
return m_Writer->m_FooterPart;
}
+// Warning: direct manipulation of MXF structures can interfere
+// with the normal operation of the wrapper. Caveat emptor!
+//
+ASDCP::MXF::RIP&
+ASDCP::JP2K::MXFWriter::RIP()
+{
+ if ( m_Writer.empty() )
+ {
+ assert(g_RIP);
+ return *g_RIP;
+ }
+
+ return m_Writer->m_RIP;
+}
+
// Open the file for writing. The file must not exist. Returns error if
// the operation cannot be completed.
ASDCP::Result_t
// Warning: direct manipulation of MXF structures can interfere
// with the normal operation of the wrapper. Caveat emptor!
//
-ASDCP::MXF::OPAtomHeader&
-ASDCP::JP2K::MXFSWriter::OPAtomHeader()
+ASDCP::MXF::OP1aHeader&
+ASDCP::JP2K::MXFSWriter::OP1aHeader()
{
if ( m_Writer.empty() )
{
- assert(g_OPAtomHeader);
- return *g_OPAtomHeader;
+ assert(g_OP1aHeader);
+ return *g_OP1aHeader;
}
return m_Writer->m_HeaderPart;
return m_Writer->m_FooterPart;
}
+// Warning: direct manipulation of MXF structures can interfere
+// with the normal operation of the wrapper. Caveat emptor!
+//
+ASDCP::MXF::RIP&
+ASDCP::JP2K::MXFSWriter::RIP()
+{
+ if ( m_Writer.empty() )
+ {
+ assert(g_RIP);
+ return *g_RIP;
+ }
+
+ return m_Writer->m_RIP;
+}
+
// Open the file for writing. The file must not exist. Returns error if
// the operation cannot be completed.
ASDCP::Result_t
/*
-Copyright (c) 2004-2012, John Hurst
+Copyright (c) 2004-2013, John Hurst
All rights reserved.
Redistribution and use in source and binary forms, with or without
VideoDescriptor m_VDesc; // video parameter list
h__Reader(const Dictionary& d) : ASDCP::h__ASDCPReader(d) {}
- ~h__Reader() {}
+ virtual ~h__Reader() {}
Result_t OpenRead(const char*);
Result_t ReadFrame(ui32_t, FrameBuffer&, AESDecContext*, HMACContext*);
Result_t ReadFrameGOPStart(ui32_t, FrameBuffer&, AESDecContext*, HMACContext*);
}
}
- if( ASDCP_SUCCESS(result) )
- result = InitMXFIndex();
-
- if( ASDCP_SUCCESS(result) )
- result = InitInfo();
-
return result;
}
// look up frame index node
IndexTableSegment::IndexEntry TmpEntry;
- if ( ASDCP_FAILURE(m_FooterPart.Lookup(FrameNum, TmpEntry)) )
+ if ( ASDCP_FAILURE(m_IndexAccess.Lookup(FrameNum, TmpEntry)) )
{
DefaultLogSink().Error("Frame value out of range: %u\n", FrameNum);
return RESULT_RANGE;
// look up frame index node
IndexTableSegment::IndexEntry TmpEntry;
- if ( ASDCP_FAILURE(m_FooterPart.Lookup(FrameNum, TmpEntry)) )
+ if ( ASDCP_FAILURE(m_IndexAccess.Lookup(FrameNum, TmpEntry)) )
{
DefaultLogSink().Error("Frame value out of range: %u\n", FrameNum);
return RESULT_RANGE;
return result;
IndexTableSegment::IndexEntry TmpEntry;
- m_FooterPart.Lookup(FrameNum, TmpEntry);
+ m_IndexAccess.Lookup(FrameNum, TmpEntry);
switch ( ( TmpEntry.Flags >> 4 ) & 0x03 )
{
// Warning: direct manipulation of MXF structures can interfere
// with the normal operation of the wrapper. Caveat emptor!
//
-ASDCP::MXF::OPAtomHeader&
-ASDCP::MPEG2::MXFReader::OPAtomHeader()
+ASDCP::MXF::OP1aHeader&
+ASDCP::MPEG2::MXFReader::OP1aHeader()
{
if ( m_Reader.empty() )
{
- assert(g_OPAtomHeader);
- return *g_OPAtomHeader;
+ assert(g_OP1aHeader);
+ return *g_OP1aHeader;
}
return m_Reader->m_HeaderPart;
return *g_OPAtomIndexFooter;
}
- return m_Reader->m_FooterPart;
+ return m_Reader->m_IndexAccess;
+}
+
+// Warning: direct manipulation of MXF structures can interfere
+// with the normal operation of the wrapper. Caveat emptor!
+//
+ASDCP::MXF::RIP&
+ASDCP::MPEG2::MXFReader::RIP()
+{
+ if ( m_Reader.empty() )
+ {
+ assert(g_RIP);
+ return *g_RIP;
+ }
+
+ return m_Reader->m_RIP;
}
// Open the file for reading. The file must exist. Returns error if the
ASDCP::MPEG2::MXFReader::DumpIndex(FILE* stream) const
{
if ( m_Reader->m_File.IsOpen() )
- m_Reader->m_FooterPart.Dump(stream);
+ m_Reader->m_IndexAccess.Dump(stream);
}
//
//------------------------------------------------------------------------------------------
//
-class ASDCP::MPEG2::MXFWriter::h__Writer : public ASDCP::h__Writer
+class ASDCP::MPEG2::MXFWriter::h__Writer : public ASDCP::h__ASDCPWriter
{
ASDCP_NO_COPY_CONSTRUCT(h__Writer);
h__Writer();
ui32_t m_GOPOffset;
byte_t m_EssenceUL[SMPTE_UL_LENGTH];
- h__Writer(const Dictionary& d) : ASDCP::h__Writer(d), m_GOPOffset(0) {
+ h__Writer(const Dictionary& d) : ASDCP::h__ASDCPWriter(d), m_GOPOffset(0) {
memset(m_EssenceUL, 0, SMPTE_UL_LENGTH);
}
- ~h__Writer(){}
+ virtual ~h__Writer(){}
Result_t OpenWrite(const char*, ui32_t HeaderSize);
Result_t SetSourceStream(const VideoDescriptor&);
{
ui32_t TCFrameRate = ( m_VDesc.EditRate == EditRate_23_98 ) ? 24 : m_VDesc.EditRate.Numerator;
- result = WriteMXFHeader(MPEG_PACKAGE_LABEL, UL(m_Dict->ul(MDD_MPEG2_VESWrapping)),
- PICT_DEF_LABEL, UL(m_EssenceUL), UL(m_Dict->ul(MDD_PictureDataDef)),
- m_VDesc.EditRate, TCFrameRate);
+ result = WriteASDCPHeader(MPEG_PACKAGE_LABEL, UL(m_Dict->ul(MDD_MPEG2_VESWrapping)),
+ PICT_DEF_LABEL, UL(m_EssenceUL), UL(m_Dict->ul(MDD_PictureDataDef)),
+ m_VDesc.EditRate, TCFrameRate);
}
return result;
m_State.Goto_FINAL();
- return WriteMXFFooter();
+ return WriteASDCPFooter();
}
// Warning: direct manipulation of MXF structures can interfere
// with the normal operation of the wrapper. Caveat emptor!
//
-ASDCP::MXF::OPAtomHeader&
-ASDCP::MPEG2::MXFWriter::OPAtomHeader()
+ASDCP::MXF::OP1aHeader&
+ASDCP::MPEG2::MXFWriter::OP1aHeader()
{
if ( m_Writer.empty() )
{
- assert(g_OPAtomHeader);
- return *g_OPAtomHeader;
+ assert(g_OP1aHeader);
+ return *g_OP1aHeader;
}
return m_Writer->m_HeaderPart;
return m_Writer->m_FooterPart;
}
+// Warning: direct manipulation of MXF structures can interfere
+// with the normal operation of the wrapper. Caveat emptor!
+//
+ASDCP::MXF::RIP&
+ASDCP::MPEG2::MXFWriter::RIP()
+{
+ if ( m_Writer.empty() )
+ {
+ assert(g_RIP);
+ return *g_RIP;
+ }
+
+ return m_Writer->m_RIP;
+}
+
// Open the file for writing. The file must not exist. Returns error if
// the operation cannot be completed.
ASDCP::Result_t
/*
-Copyright (c) 2004-2009, John Hurst
+Copyright (c) 2004-2013, John Hurst
All rights reserved.
Redistribution and use in source and binary forms, with or without
ASDCP_TEST_NULL_STR(filename);
Kumu::FileReader Reader;
- OPAtomHeader TestHeader(m_Dict);
+ OP1aHeader TestHeader(m_Dict);
Result_t result = Reader.OpenRead(filename);
{
type = ESS_TIMED_TEXT;
}
- else if ( ASDCP::ATMOS::IsDolbyAtmos(filename) )
- {
- type = ESS_DCDATA_DOLBY_ATMOS;
- }
+ else if ( ASDCP::ATMOS::IsDolbyAtmos(filename) )
+ {
+ type = ESS_DCDATA_DOLBY_ATMOS;
+ }
}
}
else if ( Kumu::PathIsDirectory(filename) )
return RESULT_FORMAT;
}
}
- else if ( ASDCP_SUCCESS(RF64Header.ReadFromBuffer(FB.RoData(), read_count, &data_offset)) )
- {
- switch ( RF64Header.samplespersec )
- {
- case 48000: type = ESS_PCM_24b_48k; break;
- case 96000: type = ESS_PCM_24b_96k; break;
- default:
- return RESULT_FORMAT;
- }
- }
- else if ( ASDCP::ATMOS::IsDolbyAtmos(Str.c_str()) )
- {
- type = ESS_DCDATA_DOLBY_ATMOS;
- }
-
+ else if ( ASDCP_SUCCESS(RF64Header.ReadFromBuffer(FB.RoData(), read_count, &data_offset)) )
+ {
+ switch ( RF64Header.samplespersec )
+ {
+ case 48000: type = ESS_PCM_24b_48k; break;
+ case 96000: type = ESS_PCM_24b_96k; break;
+ default:
+ return RESULT_FORMAT;
+ }
+ }
+ else if ( ASDCP::ATMOS::IsDolbyAtmos(Str.c_str()) )
+ {
+ type = ESS_DCDATA_DOLBY_ATMOS;
+ }
}
-
+
break;
}
}
/*
-Copyright (c) 2004-2012, John Hurst
+Copyright (c) 2004-2013, John Hurst
All rights reserved.
Redistribution and use in source and binary forms, with or without
AudioDescriptor m_ADesc;
h__Reader(const Dictionary& d) : ASDCP::h__ASDCPReader(d) {}
- ~h__Reader() {}
+ virtual ~h__Reader() {}
Result_t OpenRead(const char*);
Result_t ReadFrame(ui32_t, FrameBuffer&, AESDecContext*, HMACContext*);
};
}
}
- if( ASDCP_SUCCESS(result) )
- result = InitMXFIndex();
-
- if( ASDCP_SUCCESS(result) )
- result = InitInfo();
-
// TODO: test file for sane CBR index BytesPerEditUnit
return result;
// Warning: direct manipulation of MXF structures can interfere
// with the normal operation of the wrapper. Caveat emptor!
//
-ASDCP::MXF::OPAtomHeader&
-ASDCP::PCM::MXFReader::OPAtomHeader()
+ASDCP::MXF::OP1aHeader&
+ASDCP::PCM::MXFReader::OP1aHeader()
{
if ( m_Reader.empty() )
{
- assert(g_OPAtomHeader);
- return *g_OPAtomHeader;
+ assert(g_OP1aHeader);
+ return *g_OP1aHeader;
}
return m_Reader->m_HeaderPart;
return *g_OPAtomIndexFooter;
}
- return m_Reader->m_FooterPart;
+ return m_Reader->m_IndexAccess;
+}
+
+// Warning: direct manipulation of MXF structures can interfere
+// with the normal operation of the wrapper. Caveat emptor!
+//
+ASDCP::MXF::RIP&
+ASDCP::PCM::MXFReader::RIP()
+{
+ if ( m_Reader.empty() )
+ {
+ assert(g_RIP);
+ return *g_RIP;
+ }
+
+ return m_Reader->m_RIP;
}
// Open the file for reading. The file must exist. Returns error if the
ASDCP::PCM::MXFReader::DumpIndex(FILE* stream) const
{
if ( m_Reader->m_File.IsOpen() )
- m_Reader->m_FooterPart.Dump(stream);
+ m_Reader->m_IndexAccess.Dump(stream);
}
//
//------------------------------------------------------------------------------------------
//
-class ASDCP::PCM::MXFWriter::h__Writer : public ASDCP::h__Writer
+class ASDCP::PCM::MXFWriter::h__Writer : public ASDCP::h__ASDCPWriter
{
ASDCP_NO_COPY_CONSTRUCT(h__Writer);
h__Writer();
AudioDescriptor m_ADesc;
byte_t m_EssenceUL[SMPTE_UL_LENGTH];
- h__Writer(const Dictionary& d) : ASDCP::h__Writer(d) {
+ h__Writer(const Dictionary& d) : ASDCP::h__ASDCPWriter(d) {
memset(m_EssenceUL, 0, SMPTE_UL_LENGTH);
}
- ~h__Writer(){}
+ virtual ~h__Writer(){}
Result_t OpenWrite(const char*, ui32_t HeaderSize);
Result_t SetSourceStream(const AudioDescriptor&);
else if ( m_ADesc.EditRate == EditRate_22 )
TCFrameRate = 22;
- result = WriteMXFHeader(PCM_PACKAGE_LABEL, UL(m_Dict->ul(MDD_WAVWrapping)),
- SOUND_DEF_LABEL, UL(m_EssenceUL), UL(m_Dict->ul(MDD_SoundDataDef)),
- m_ADesc.EditRate, TCFrameRate, calc_CBR_frame_size(m_Info, m_ADesc));
+ result = WriteASDCPHeader(PCM_PACKAGE_LABEL, UL(m_Dict->ul(MDD_WAVWrapping)),
+ SOUND_DEF_LABEL, UL(m_EssenceUL), UL(m_Dict->ul(MDD_SoundDataDef)),
+ m_ADesc.EditRate, TCFrameRate, calc_CBR_frame_size(m_Info, m_ADesc));
}
return result;
m_State.Goto_FINAL();
- return WriteMXFFooter();
+ return WriteASDCPFooter();
}
// Warning: direct manipulation of MXF structures can interfere
// with the normal operation of the wrapper. Caveat emptor!
//
-ASDCP::MXF::OPAtomHeader&
-ASDCP::PCM::MXFWriter::OPAtomHeader()
+ASDCP::MXF::OP1aHeader&
+ASDCP::PCM::MXFWriter::OP1aHeader()
{
if ( m_Writer.empty() )
{
- assert(g_OPAtomHeader);
- return *g_OPAtomHeader;
+ assert(g_OP1aHeader);
+ return *g_OP1aHeader;
}
return m_Writer->m_HeaderPart;
return m_Writer->m_FooterPart;
}
+// Warning: direct manipulation of MXF structures can interfere
+// with the normal operation of the wrapper. Caveat emptor!
+//
+ASDCP::MXF::RIP&
+ASDCP::PCM::MXFWriter::RIP()
+{
+ if ( m_Writer.empty() )
+ {
+ assert(g_RIP);
+ return *g_RIP;
+ }
+
+ return m_Writer->m_RIP;
+}
+
// Open the file for writing. The file must not exist. Returns error if
// the operation cannot be completed.
ASDCP::Result_t
/*
-Copyright (c) 2008-2012, John Hurst
+Copyright (c) 2008-2013, John Hurst
All rights reserved.
Redistribution and use in source and binary forms, with or without
memset(&m_TDesc.AssetID, 0, UUIDlen);
}
+ virtual ~h__Reader() {}
+
Result_t OpenRead(const char*);
Result_t MD_to_TimedText_TDesc(TimedText::TimedTextDescriptor& TDesc);
Result_t ReadTimedTextResource(FrameBuffer& FrameBuf, AESDecContext* Ctx, HMACContext* HMAC);
result = MD_to_TimedText_TDesc(m_TDesc);
}
- if( ASDCP_SUCCESS(result) )
- result = InitMXFIndex();
-
- if( ASDCP_SUCCESS(result) )
- result = InitInfo();
-
return result;
}
// Look up the partition start in the RIP using the SID.
// Count the sequence length in because this is the sequence
// value needed to complete the HMAC.
- for ( pi = m_HeaderPart.m_RIP.PairArray.begin(); pi != m_HeaderPart.m_RIP.PairArray.end(); ++pi, ++sequence )
+ for ( pi = m_RIP.PairArray.begin(); pi != m_RIP.PairArray.end(); ++pi, ++sequence )
{
if ( (*pi).BodySID == DescObject->EssenceStreamID )
{
// Warning: direct manipulation of MXF structures can interfere
// with the normal operation of the wrapper. Caveat emptor!
//
-ASDCP::MXF::OPAtomHeader&
-ASDCP::TimedText::MXFReader::OPAtomHeader()
+ASDCP::MXF::OP1aHeader&
+ASDCP::TimedText::MXFReader::OP1aHeader()
{
if ( m_Reader.empty() )
{
- assert(g_OPAtomHeader);
- return *g_OPAtomHeader;
+ assert(g_OP1aHeader);
+ return *g_OP1aHeader;
}
return m_Reader->m_HeaderPart;
return *g_OPAtomIndexFooter;
}
- return m_Reader->m_FooterPart;
+ return m_Reader->m_IndexAccess;
+}
+
+// Warning: direct manipulation of MXF structures can interfere
+// with the normal operation of the wrapper. Caveat emptor!
+//
+ASDCP::MXF::RIP&
+ASDCP::TimedText::MXFReader::RIP()
+{
+ if ( m_Reader.empty() )
+ {
+ assert(g_RIP);
+ return *g_RIP;
+ }
+
+ return m_Reader->m_RIP;
}
// Open the file for reading. The file must exist. Returns error if the
ASDCP::TimedText::MXFReader::DumpIndex(FILE* stream) const
{
if ( m_Reader->m_File.IsOpen() )
- m_Reader->m_FooterPart.Dump(stream);
+ m_Reader->m_IndexAccess.Dump(stream);
}
//
//
-class ASDCP::TimedText::MXFWriter::h__Writer : public ASDCP::h__Writer
+class ASDCP::TimedText::MXFWriter::h__Writer : public ASDCP::h__ASDCPWriter
{
ASDCP_NO_COPY_CONSTRUCT(h__Writer);
h__Writer();
byte_t m_EssenceUL[SMPTE_UL_LENGTH];
ui32_t m_EssenceStreamID;
- h__Writer(const Dictionary& d) : ASDCP::h__Writer(d), m_EssenceStreamID(10) {
+ h__Writer(const Dictionary& d) : ASDCP::h__ASDCPWriter(d), m_EssenceStreamID(10) {
memset(m_EssenceUL, 0, SMPTE_UL_LENGTH);
}
- ~h__Writer(){}
+ virtual ~h__Writer() {}
Result_t OpenWrite(const char*, ui32_t HeaderSize);
Result_t SetSourceStream(const TimedTextDescriptor&);
MXF::Partition GSPart(m_Dict);
GSPart.ThisPartition = here;
- GSPart.PreviousPartition = m_HeaderPart.m_RIP.PairArray.back().ByteOffset;
+ GSPart.PreviousPartition = m_RIP.PairArray.back().ByteOffset;
GSPart.BodySID = m_EssenceStreamID;
GSPart.OperationalPattern = m_HeaderPart.OperationalPattern;
- m_HeaderPart.m_RIP.PairArray.push_back(RIP::Pair(m_EssenceStreamID++, here));
+ m_RIP.PairArray.push_back(RIP::Pair(m_EssenceStreamID++, here));
GSPart.EssenceContainers.push_back(UL(m_Dict->ul(MDD_TimedTextEssence)));
UL TmpUL(m_Dict->ul(MDD_GenericStreamPartition));
Result_t result = GSPart.WriteToFile(m_File, TmpUL);
m_FramesWritten = m_TDesc.ContainerDuration;
m_State.Goto_FINAL();
- return WriteMXFFooter();
+ return WriteASDCPFooter();
}
// Warning: direct manipulation of MXF structures can interfere
// with the normal operation of the wrapper. Caveat emptor!
//
-ASDCP::MXF::OPAtomHeader&
-ASDCP::TimedText::MXFWriter::OPAtomHeader()
+ASDCP::MXF::OP1aHeader&
+ASDCP::TimedText::MXFWriter::OP1aHeader()
{
if ( m_Writer.empty() )
{
- assert(g_OPAtomHeader);
- return *g_OPAtomHeader;
+ assert(g_OP1aHeader);
+ return *g_OP1aHeader;
}
return m_Writer->m_HeaderPart;
return m_Writer->m_FooterPart;
}
+// Warning: direct manipulation of MXF structures can interfere
+// with the normal operation of the wrapper. Caveat emptor!
+//
+ASDCP::MXF::RIP&
+ASDCP::TimedText::MXFWriter::RIP()
+{
+ if ( m_Writer.empty() )
+ {
+ assert(g_RIP);
+ return *g_RIP;
+ }
+
+ return m_Writer->m_RIP;
+}
+
// Open the file for writing. The file must not exist. Returns error if
// the operation cannot be completed.
ASDCP::Result_t
/*
-Copyright (c) 2004-2012, John Hurst
+Copyright (c) 2004-2013, John Hurst
All rights reserved.
Redistribution and use in source and binary forms, with or without
#include "Metadata.h"
using Kumu::DefaultLogSink;
-// using namespace std;
using namespace ASDCP;
using namespace ASDCP::MXF;
+// a magic number identifying asdcplib
+#ifndef ASDCP_BUILD_NUMBER
+#define ASDCP_BUILD_NUMBER 0x6A68
+#endif
+
+
#ifdef DEFAULT_MD_DECL
-ASDCP::MXF::OPAtomHeader *g_OPAtomHeader;
+ASDCP::MXF::OP1aHeader *g_OP1aHeader;
ASDCP::MXF::OPAtomIndexFooter *g_OPAtomIndexFooter;
+ASDCP::MXF::RIP *g_RIP;
#else
-extern MXF::OPAtomHeader *g_OPAtomHeader;
+extern MXF::OP1aHeader *g_OP1aHeader;
extern MXF::OPAtomIndexFooter *g_OPAtomIndexFooter;
+extern MXF::RIP *g_RIP;
#endif
void AddDMScrypt(Partition& HeaderPart, SourcePackage& Package,
WriterInfo& Descr, const UL& WrappingUL, const Dictionary*& Dict);
- Result_t Read_EKLV_Packet(Kumu::FileReader& File, const ASDCP::Dictionary& Dict, const MXF::OPAtomHeader& HeaderPart,
+ Result_t Read_EKLV_Packet(Kumu::FileReader& File, const ASDCP::Dictionary& Dict, const MXF::OP1aHeader& HeaderPart,
const ASDCP::WriterInfo& Info, Kumu::fpos_t& LastPosition, ASDCP::FrameBuffer& CtFrameBuf,
ui32_t FrameNum, ui32_t SequenceNum, ASDCP::FrameBuffer& FrameBuf,
const byte_t* EssenceUL, AESDecContext* Ctx, HMACContext* HMAC);
+ Result_t Write_EKLV_Packet(Kumu::FileWriter& File, const ASDCP::Dictionary& Dict, const MXF::OP1aHeader& HeaderPart,
+ const ASDCP::WriterInfo& Info, ASDCP::FrameBuffer& CtFrameBuf, ui32_t& FramesWritten,
+ ui64_t & StreamOffset, const ASDCP::FrameBuffer& FrameBuf, const byte_t* EssenceUL,
+ AESEncContext* Ctx, HMACContext* HMAC);
+
//
class KLReader : public ASDCP::KLVPacket
{
/// void default_md_object_init();
- template <class HeaderType, class FooterType>
+ template <class HeaderType, class IndexAccessType>
class TrackFileReader
{
KM_NO_COPY_CONSTRUCT(TrackFileReader);
const Dictionary* m_Dict;
Kumu::FileReader m_File;
HeaderType m_HeaderPart;
- FooterType m_FooterPart;
+ IndexAccessType m_IndexAccess;
+ RIP m_RIP;
WriterInfo m_Info;
ASDCP::FrameBuffer m_CtFrameBuf;
Kumu::fpos_t m_LastPosition;
TrackFileReader(const Dictionary& d) :
- m_HeaderPart(m_Dict), m_FooterPart(m_Dict), m_Dict(&d)
+ m_HeaderPart(m_Dict), m_IndexAccess(m_Dict), m_RIP(m_Dict), m_Dict(&d)
{
default_md_object_init();
}
Close();
}
+ const MXF::RIP& GetRIP() const { return m_RIP; }
+
+ //
+ Result_t OpenMXFRead(const char* filename)
+ {
+ m_LastPosition = 0;
+ Result_t result = m_File.OpenRead(filename);
+
+ if ( ASDCP_SUCCESS(result) )
+ result = SeekToRIP(m_File);
+
+ if ( ASDCP_SUCCESS(result) )
+ {
+ result = m_RIP.InitFromFile(m_File);
+ ui32_t test_s = m_RIP.PairArray.size();
+
+ if ( ASDCP_FAILURE(result) )
+ {
+ DefaultLogSink().Error("File contains no RIP\n");
+ }
+ else if ( m_RIP.PairArray.empty() )
+ {
+ DefaultLogSink().Error("RIP contains no Pairs.\n");
+ }
+ }
+ else
+ {
+ DefaultLogSink().Error("TrackFileReader::OpenMXFRead, SeekToRIP failed\n");
+ }
+
+ m_File.Seek(0);
+ result = m_HeaderPart.InitFromFile(m_File);
+
+ if ( KM_FAILURE(result) )
+ {
+ DefaultLogSink().Error("TrackFileReader::OpenMXFRead, header init failed\n");
+ }
+
+ return result;
+ }
+
+ //
Result_t InitInfo()
{
assert(m_Dict);
return result;
}
- //
- Result_t OpenMXFRead(const char* filename)
- {
- m_LastPosition = 0;
- Result_t result = m_File.OpenRead(filename);
-
- if ( KM_SUCCESS(result) )
- result = m_HeaderPart.InitFromFile(m_File);
- else
- DefaultLogSink().Error("ASDCP::h__Reader::OpenMXFRead, OpenRead failed\n");
-
- return result;
- }
-
// positions file before reading
Result_t ReadEKLVFrame(const ASDCP::MXF::Partition& CurrentPartition,
ui32_t FrameNum, ASDCP::FrameBuffer& FrameBuf,
// look up frame index node
IndexTableSegment::IndexEntry TmpEntry;
- if ( KM_FAILURE(m_FooterPart.Lookup(FrameNum, TmpEntry)) )
+ if ( KM_FAILURE(m_IndexAccess.Lookup(FrameNum, TmpEntry)) )
{
DefaultLogSink().Error("Frame value out of range: %u\n", FrameNum);
return RESULT_RANGE;
FrameNum, SequenceNum, FrameBuf, EssenceUL, Ctx, HMAC);
}
- // Get the position of a frame from a track file
- Result_t LocateFrame(const ASDCP::MXF::Partition& CurrentPartition,
- ui32_t FrameNum, Kumu::fpos_t& streamOffset,
- i8_t& temporalOffset, i8_t& keyFrameOffset)
- {
- // look up frame index node
- IndexTableSegment::IndexEntry TmpEntry;
+ // Get the position of a frame from a track file
+ Result_t LocateFrame(const ASDCP::MXF::Partition& CurrentPartition,
+ ui32_t FrameNum, Kumu::fpos_t& streamOffset,
+ i8_t& temporalOffset, i8_t& keyFrameOffset)
+ {
+ // look up frame index node
+ IndexTableSegment::IndexEntry TmpEntry;
+
+ if ( KM_FAILURE(m_IndexAccess.Lookup(FrameNum, TmpEntry)) )
+ {
+ DefaultLogSink().Error("Frame value out of range: %u\n", FrameNum);
+ return RESULT_RANGE;
+ }
+
+ // get frame position, temporal offset, and key frame ofset
+ streamOffset = CurrentPartition.BodyOffset + TmpEntry.StreamOffset;
+ temporalOffset = TmpEntry.TemporalOffset;
+ keyFrameOffset = TmpEntry.KeyFrameOffset;
+
+ return RESULT_OK;
+ }
+
+ //
+ void Close()
+ {
+ m_File.Close();
+ }
+ };
+
+
+ //
+ //
+ 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(OP1aHeader& Header, PackageT& Package, const std::string TrackName,
+ const MXF::Rational& EditRate, const UL& Definition, ui32_t TrackID, const Dictionary*& Dict)
+ {
+ TrackSet<ClipT> NewTrack;
+
+ NewTrack.Track = new Track(Dict);
+ 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(Dict);
+ Header.AddChildObject(NewTrack.Sequence);
+ NewTrack.Track->Sequence = NewTrack.Sequence->InstanceUID;
+ NewTrack.Sequence->DataDefinition = Definition;
+
+ return NewTrack;
+ }
+
+ //
+ template <class PackageT>
+ TrackSet<TimecodeComponent>
+ CreateTimecodeTrack(OP1aHeader& Header, PackageT& Package,
+ const MXF::Rational& EditRate, ui32_t TCFrameRate, ui64_t TCStart, const Dictionary*& Dict)
+ {
+ assert(Dict);
+ UL TCUL(Dict->ul(MDD_TimecodeDataDef));
+
+ TrackSet<TimecodeComponent> NewTrack = CreateTrackAndSequence<PackageT, TimecodeComponent>(Header, Package, "Timecode Track", EditRate, TCUL, 1, Dict);
+
+ NewTrack.Clip = new TimecodeComponent(Dict);
+ 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;
+ }
+
+
+ // state machine for mxf writer
+ enum WriterState_t {
+ ST_BEGIN, // waiting for Open()
+ ST_INIT, // waiting for SetSourceStream()
+ ST_READY, // ready to write frames
+ ST_RUNNING, // one or more frames written
+ ST_FINAL, // index written, file closed
+ };
- if ( KM_FAILURE(m_FooterPart.Lookup(FrameNum, TmpEntry)) )
+ // implementation of h__WriterState class Goto_* methods
+#define Goto_body(s1,s2) \
+ if ( m_State != (s1) ) { \
+ return RESULT_STATE; \
+ } \
+ m_State = (s2); \
+ return RESULT_OK
+ //
+ class h__WriterState
{
- DefaultLogSink().Error("Frame value out of range: %u\n", FrameNum);
- return RESULT_RANGE;
- }
+ ASDCP_NO_COPY_CONSTRUCT(h__WriterState);
+
+ public:
+ WriterState_t m_State;
+ h__WriterState() : m_State(ST_BEGIN) {}
+ ~h__WriterState() {}
+
+ inline bool Test_BEGIN() { return m_State == ST_BEGIN; }
+ inline bool Test_INIT() { return m_State == ST_INIT; }
+ inline bool Test_READY() { return m_State == ST_READY;}
+ inline bool Test_RUNNING() { return m_State == ST_RUNNING; }
+ inline bool Test_FINAL() { return m_State == ST_FINAL; }
+ inline Result_t Goto_INIT() { Goto_body(ST_BEGIN, ST_INIT); }
+ inline Result_t Goto_READY() { Goto_body(ST_INIT, ST_READY); }
+ inline Result_t Goto_RUNNING() { Goto_body(ST_READY, ST_RUNNING); }
+ inline Result_t Goto_FINAL() { Goto_body(ST_RUNNING, ST_FINAL); }
+ };
- // get frame position, temporal offset, and key frame ofset
- streamOffset = CurrentPartition.BodyOffset + TmpEntry.StreamOffset;
- temporalOffset = TmpEntry.TemporalOffset;
- keyFrameOffset = TmpEntry.KeyFrameOffset;
+ //
+ //
+ template <class HeaderType>
+ class TrackFileWriter
+ {
+ KM_NO_COPY_CONSTRUCT(TrackFileWriter);
+ TrackFileWriter();
- return RESULT_OK;
- }
+ public:
+ const Dictionary* m_Dict;
+ Kumu::FileWriter m_File;
+ ui32_t m_HeaderSize;
+ HeaderType m_HeaderPart;
+ RIP m_RIP;
+ ui64_t m_EssenceStart;
+
+ MaterialPackage* m_MaterialPackage;
+ SourcePackage* m_FilePackage;
+
+ FileDescriptor* m_EssenceDescriptor;
+ std::list<InterchangeObject*> m_EssenceSubDescriptorList;
+
+ ui32_t m_FramesWritten;
+ ui64_t m_StreamOffset;
+ ASDCP::FrameBuffer m_CtFrameBuf;
+ h__WriterState m_State;
+ WriterInfo m_Info;
+
+ typedef std::list<ui64_t*> DurationElementList_t;
+ DurationElementList_t m_DurationUpdateList;
+
+ TrackFileWriter(const Dictionary& d) :
+ m_Dict(&d), m_HeaderPart(m_Dict), m_RIP(m_Dict),
+ m_HeaderSize(0), m_EssenceStart(0), m_EssenceDescriptor(0),
+ m_FramesWritten(0), m_StreamOffset(0)
+ {
+ default_md_object_init();
+ }
+
+ virtual ~TrackFileWriter() {}
+
+ const MXF::RIP& GetRIP() const { return m_RIP; }
+
+ void InitHeader()
+ {
+ assert(m_Dict);
+ assert(m_EssenceDescriptor);
+
+ m_HeaderPart.m_Primer.ClearTagList();
+ m_HeaderPart.m_Preface = new Preface(m_Dict);
+ m_HeaderPart.AddChildObject(m_HeaderPart.m_Preface);
+
+ // Set the Operational Pattern label -- we're just starting and have no RIP or index,
+ // so we tell the world by using OP1a
+ m_HeaderPart.m_Preface->OperationalPattern = UL(m_Dict->ul(MDD_OP1a));
+ m_HeaderPart.OperationalPattern = m_HeaderPart.m_Preface->OperationalPattern;
+
+ // Identification
+ Identification* Ident = new Identification(m_Dict);
+ m_HeaderPart.AddChildObject(Ident);
+ m_HeaderPart.m_Preface->Identifications.push_back(Ident->InstanceUID);
+
+ Kumu::GenRandomValue(Ident->ThisGenerationUID);
+ Ident->CompanyName = m_Info.CompanyName.c_str();
+ Ident->ProductName = m_Info.ProductName.c_str();
+ Ident->VersionString = m_Info.ProductVersion.c_str();
+ Ident->ProductUID.Set(m_Info.ProductUUID);
+ Ident->Platform = ASDCP_PLATFORM;
+
+ std::vector<int> version = version_split(Version());
+
+ Ident->ToolkitVersion.Major = version[0];
+ Ident->ToolkitVersion.Minor = version[1];
+ Ident->ToolkitVersion.Patch = version[2];
+ Ident->ToolkitVersion.Build = ASDCP_BUILD_NUMBER;
+ Ident->ToolkitVersion.Release = VersionType::RL_RELEASE;
+ }
//
- void Close() {
+ void AddSourceClip(const MXF::Rational& EditRate, ui32_t TCFrameRate,
+ const std::string& TrackName, const UL& EssenceUL,
+ const UL& DataDefinition, const std::string& PackageLabel)
+ {
+ //
+ ContentStorage* Storage = new ContentStorage(m_Dict);
+ m_HeaderPart.AddChildObject(Storage);
+ m_HeaderPart.m_Preface->ContentStorage = Storage->InstanceUID;
+
+ EssenceContainerData* ECD = new EssenceContainerData(m_Dict);
+ m_HeaderPart.AddChildObject(ECD);
+ Storage->EssenceContainerData.push_back(ECD->InstanceUID);
+ 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
+ //
+ m_MaterialPackage = new MaterialPackage(m_Dict);
+ 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_Dict);
+ m_DurationUpdateList.push_back(&(MPTCTrack.Sequence->Duration));
+ m_DurationUpdateList.push_back(&(MPTCTrack.Clip->Duration));
+
+ TrackSet<SourceClip> MPTrack =
+ CreateTrackAndSequence<MaterialPackage, SourceClip>(m_HeaderPart, *m_MaterialPackage,
+ TrackName, EditRate, DataDefinition,
+ 2, m_Dict);
+ m_DurationUpdateList.push_back(&(MPTrack.Sequence->Duration));
+
+ MPTrack.Clip = new SourceClip(m_Dict);
+ 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_Dict);
+ 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_Dict);
+ 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_Dict);
+ m_DurationUpdateList.push_back(&(FPTrack.Sequence->Duration));
+
+ // Consult ST 379:2004 Sec. 6.3, "Element to track relationship" to see where "12" comes from.
+ FPTrack.Track->TrackNumber = KM_i32_BE(Kumu::cp2i<ui32_t>((EssenceUL.Value() + 12)));
+
+ FPTrack.Clip = new SourceClip(m_Dict);
+ 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 AddDMSegment(const MXF::Rational& EditRate, ui32_t TCFrameRate,
+ const std::string& TrackName, const UL& DataDefinition,
+ const std::string& PackageLabel)
+ {
+ //
+ ContentStorage* Storage = new ContentStorage(m_Dict);
+ m_HeaderPart.AddChildObject(Storage);
+ m_HeaderPart.m_Preface->ContentStorage = Storage->InstanceUID;
+
+ EssenceContainerData* ECD = new EssenceContainerData(m_Dict);
+ m_HeaderPart.AddChildObject(ECD);
+ Storage->EssenceContainerData.push_back(ECD->InstanceUID);
+ 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
+ //
+ m_MaterialPackage = new MaterialPackage(m_Dict);
+ 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_Dict);
+ 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_Dict);
+ m_DurationUpdateList.push_back(&(MPTrack.Sequence->Duration));
+
+ MPTrack.Clip = new DMSegment(m_Dict);
+ 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_Dict);
+ 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_Dict);
+ m_DurationUpdateList.push_back(&(FPTCTrack.Sequence->Duration));
+ m_DurationUpdateList.push_back(&(FPTCTrack.Clip->Duration));
+
+ TrackSet<DMSegment> FPTrack =
+ CreateTrackAndSequence<SourcePackage, DMSegment>(m_HeaderPart, *m_FilePackage,
+ TrackName, EditRate, DataDefinition,
+ 2, m_Dict);
+ m_DurationUpdateList.push_back(&(FPTrack.Sequence->Duration));
+
+ FPTrack.Clip = new DMSegment(m_Dict);
+ 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 AddEssenceDescriptor(const UL& WrappingUL)
+ {
+ //
+ // Essence Descriptor
+ //
+ m_EssenceDescriptor->EssenceContainer = WrappingUL;
+ m_HeaderPart.m_Preface->PrimaryPackage = m_FilePackage->InstanceUID;
+
+ //
+ // Essence Descriptors
+ //
+ assert(m_Dict);
+ UL GenericContainerUL(m_Dict->ul(MDD_GCMulti));
+ m_HeaderPart.EssenceContainers.push_back(GenericContainerUL);
+
+ if ( m_Info.EncryptedEssence )
+ {
+ UL CryptEssenceUL(m_Dict->ul(MDD_EncryptedContainerLabel));
+ m_HeaderPart.EssenceContainers.push_back(CryptEssenceUL);
+ m_HeaderPart.m_Preface->DMSchemes.push_back(UL(m_Dict->ul(MDD_CryptographicFrameworkLabel)));
+ AddDMScrypt(m_HeaderPart, *m_FilePackage, m_Info, WrappingUL, m_Dict);
+ }
+ else
+ {
+ m_HeaderPart.EssenceContainers.push_back(WrappingUL);
+ }
+
+ m_HeaderPart.m_Preface->EssenceContainers = m_HeaderPart.EssenceContainers;
+ m_HeaderPart.AddChildObject(m_EssenceDescriptor);
+
+ std::list<InterchangeObject*>::iterator sdli = m_EssenceSubDescriptorList.begin();
+ for ( ; sdli != m_EssenceSubDescriptorList.end(); sdli++ )
+ m_HeaderPart.AddChildObject(*sdli);
+
+ m_FilePackage->Descriptor = m_EssenceDescriptor->InstanceUID;
+ }
+
+ //
+ Result_t WriteEKLVPacket(const ASDCP::FrameBuffer& FrameBuf,const byte_t* EssenceUL, AESEncContext* Ctx, HMACContext* HMAC)
+ {
+ return Write_EKLV_Packet(m_File, *m_Dict, m_HeaderPart, m_Info, m_CtFrameBuf, m_FramesWritten,
+ m_StreamOffset, FrameBuf, EssenceUL, Ctx, HMAC);
+ }
+
+ //
+ void Close()
+ {
m_File.Close();
}
- };
+ };
+
}/// namespace MXF
//
- class h__ASDCPReader : public MXF::TrackFileReader<OPAtomHeader, OPAtomIndexFooter>
+ class h__ASDCPReader : public MXF::TrackFileReader<OP1aHeader, OPAtomIndexFooter>
{
ASDCP_NO_COPY_CONSTRUCT(h__ASDCPReader);
h__ASDCPReader();
virtual ~h__ASDCPReader();
Result_t OpenMXFRead(const char* filename);
- Result_t InitInfo();
- Result_t InitMXFIndex();
Result_t ReadEKLVFrame(ui32_t FrameNum, ASDCP::FrameBuffer& FrameBuf,
const byte_t* EssenceUL, AESDecContext* Ctx, HMACContext* HMAC);
Result_t LocateFrame(ui32_t FrameNum, Kumu::fpos_t& streamOffset,
i8_t& temporalOffset, i8_t& keyFrameOffset);
-
- };
-
-
- // state machine for mxf writer
- enum WriterState_t {
- ST_BEGIN, // waiting for Open()
- ST_INIT, // waiting for SetSourceStream()
- ST_READY, // ready to write frames
- ST_RUNNING, // one or more frames written
- ST_FINAL, // index written, file closed
- };
-
- // implementation of h__WriterState class Goto_* methods
-#define Goto_body(s1,s2) if ( m_State != (s1) ) \
- return RESULT_STATE; \
- m_State = (s2); \
- return RESULT_OK
- //
- class h__WriterState
- {
- ASDCP_NO_COPY_CONSTRUCT(h__WriterState);
-
- public:
- WriterState_t m_State;
- h__WriterState() : m_State(ST_BEGIN) {}
- ~h__WriterState() {}
-
- inline bool Test_BEGIN() { return m_State == ST_BEGIN; }
- inline bool Test_INIT() { return m_State == ST_INIT; }
- inline bool Test_READY() { return m_State == ST_READY;}
- inline bool Test_RUNNING() { return m_State == ST_RUNNING; }
- inline bool Test_FINAL() { return m_State == ST_FINAL; }
- inline Result_t Goto_INIT() { Goto_body(ST_BEGIN, ST_INIT); }
- inline Result_t Goto_READY() { Goto_body(ST_INIT, ST_READY); }
- inline Result_t Goto_RUNNING() { Goto_body(ST_READY, ST_RUNNING); }
- inline Result_t Goto_FINAL() { Goto_body(ST_RUNNING, ST_FINAL); }
};
- typedef std::list<ui64_t*> DurationElementList_t;
-
//
- class h__Writer
+ class h__ASDCPWriter : public MXF::TrackFileWriter<OP1aHeader>
{
- ASDCP_NO_COPY_CONSTRUCT(h__Writer);
- h__Writer();
+ ASDCP_NO_COPY_CONSTRUCT(h__ASDCPWriter);
+ h__ASDCPWriter();
public:
- const Dictionary* m_Dict;
- Kumu::FileWriter m_File;
- ui32_t m_HeaderSize;
- OPAtomHeader m_HeaderPart;
Partition m_BodyPart;
OPAtomIndexFooter m_FooterPart;
- ui64_t m_EssenceStart;
-
- MaterialPackage* m_MaterialPackage;
- SourcePackage* m_FilePackage;
-
- FileDescriptor* m_EssenceDescriptor;
- std::list<InterchangeObject*> m_EssenceSubDescriptorList;
-
- ui32_t m_FramesWritten;
- ui64_t m_StreamOffset;
- ASDCP::FrameBuffer m_CtFrameBuf;
- h__WriterState m_State;
- WriterInfo m_Info;
- DurationElementList_t m_DurationUpdateList;
-
- h__Writer(const Dictionary&);
- virtual ~h__Writer();
-
- void InitHeader();
- void AddSourceClip(const MXF::Rational& EditRate, ui32_t TCFrameRate,
- const std::string& TrackName, const UL& EssenceUL,
- 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& EssenceUL,
- const UL& DataDefinition, const MXF::Rational& EditRate,
- ui32_t TCFrameRate, ui32_t BytesPerEditUnit = 0);
+ h__ASDCPWriter(const Dictionary&);
+ virtual ~h__ASDCPWriter();
- Result_t WriteEKLVPacket(const ASDCP::FrameBuffer& FrameBuf,
- const byte_t* EssenceUL, AESEncContext* Ctx, HMACContext* HMAC);
+ Result_t CreateBodyPart(const MXF::Rational& EditRate, ui32_t BytesPerEditUnit = 0);
- Result_t WriteMXFFooter();
+ // all the above for a single source clip
+ Result_t WriteASDCPHeader(const std::string& PackageLabel, const UL& WrappingUL,
+ const std::string& TrackName, const UL& EssenceUL,
+ const UL& DataDefinition, const MXF::Rational& EditRate,
+ ui32_t TCFrameRate, ui32_t BytesPerEditUnit = 0);
- };
+ Result_t WriteASDCPFooter();
+ };
// helper class for calculating Integrity Packs, used by WriteEKLVPacket() below.
/*
-Copyright (c) 2005-2012, John Hurst
+Copyright (c) 2005-2013, John Hurst
All rights reserved.
Redistribution and use in source and binary forms, with or without
//------------------------------------------------------------------------------------------
//
-ASDCP::MXF::OPAtomHeader::OPAtomHeader(const Dictionary*& d) : Partition(d), m_Dict(d), m_RIP(d), m_Primer(d), m_Preface(0), m_HasRIP(false) {}
-ASDCP::MXF::OPAtomHeader::~OPAtomHeader() {}
+ASDCP::MXF::OP1aHeader::OP1aHeader(const Dictionary*& d) : Partition(d), m_Dict(d), m_Primer(d), m_Preface(0) {}
+ASDCP::MXF::OP1aHeader::~OP1aHeader() {}
//
ASDCP::Result_t
-ASDCP::MXF::OPAtomHeader::InitFromFile(const Kumu::FileReader& Reader)
+ASDCP::MXF::OP1aHeader::InitFromFile(const Kumu::FileReader& Reader)
{
- m_HasRIP = false;
- Result_t result = SeekToRIP(Reader);
+ Result_t result = result = Partition::InitFromFile(Reader);
- if ( ASDCP_SUCCESS(result) )
- {
- result = m_RIP.InitFromFile(Reader);
- ui32_t test_s = m_RIP.PairArray.size();
+ if ( ASDCP_FAILURE(result) )
+ return result;
- if ( ASDCP_FAILURE(result) )
- {
- DefaultLogSink().Error("File contains no RIP\n");
- result = RESULT_OK;
- }
- else if ( test_s == 0 )
+ if ( m_Dict == &DefaultCompositeDict() )
+ {
+ // select more explicit dictionary if one is available
+ if ( OperationalPattern.ExactMatch(MXFInterop_OPAtom_Entry().ul) )
{
- DefaultLogSink().Error("RIP contains no Pairs.\n");
- result = RESULT_FORMAT;
+ m_Dict = &DefaultInteropDict();
}
- else
+ else if ( OperationalPattern.ExactMatch(SMPTE_390_OPAtom_Entry().ul) )
{
- if ( test_s < 2 )
- {
- // OP-Atom states that there will be either two or three partitions:
- // one closed header and one closed footer with an optional body
- // SMPTE 429-5 files may have many partitions, see SMPTE 410M
- DefaultLogSink().Warn("RIP count is less than 2: %u\n", test_s);
- }
-
- m_HasRIP = true;
-
- if ( m_RIP.PairArray.front().ByteOffset != 0 )
- {
- DefaultLogSink().Error("First Partition in RIP is not at offset 0.\n");
- result = RESULT_FORMAT;
- }
+ m_Dict = &DefaultSMPTEDict();
}
}
- else
- {
- DefaultLogSink().Error("OPAtomHeader::InitFromFile, SeekToRIP failed\n");
- }
-
- if ( ASDCP_SUCCESS(result) )
- result = Reader.Seek(0);
- else
- DefaultLogSink().Error("OPAtomHeader::InitFromFile, Seek failed\n");
-
- if ( ASDCP_SUCCESS(result) )
- result = Partition::InitFromFile(Reader); // test UL and OP
- else
- DefaultLogSink().Error("OPAtomHeader::InitFromFile, Partition::InitFromFile failed\n");
-
- if ( ASDCP_FAILURE(result) )
- return result;
-
- // is it really OP-Atom?
- assert(m_Dict);
- UL OPAtomUL(SMPTE_390_OPAtom_Entry().ul);
- UL InteropOPAtomUL(MXFInterop_OPAtom_Entry().ul);
-
- if ( OperationalPattern.ExactMatch(OPAtomUL) ) // SMPTE
- {
- if ( m_Dict == &DefaultCompositeDict() )
- m_Dict = &DefaultSMPTEDict();
- }
- else if ( OperationalPattern.ExactMatch(InteropOPAtomUL) ) // Interop
- {
- if ( m_Dict == &DefaultCompositeDict() )
- m_Dict = &DefaultInteropDict();
- }
- else
- {
- char strbuf[IdentBufferLen];
- const MDDEntry* Entry = m_Dict->FindUL(OperationalPattern.Value());
- if ( Entry == 0 )
- DefaultLogSink().Warn("Operational pattern is not OP-Atom: %s\n",
- OperationalPattern.EncodeString(strbuf, IdentBufferLen));
- else
- DefaultLogSink().Warn("Operational pattern is not OP-Atom: %s\n", Entry->name);
- }
// slurp up the remainder of the header
if ( HeaderByteCount < 1024 )
DefaultLogSink().Warn("Improbably small HeaderByteCount value: %u\n", HeaderByteCount);
assert (HeaderByteCount <= 0xFFFFFFFFL);
- result = m_Buffer.Capacity((ui32_t) HeaderByteCount);
+ result = m_HeaderData.Capacity((ui32_t)HeaderByteCount);
if ( ASDCP_SUCCESS(result) )
{
ui32_t read_count;
- result = Reader.Read(m_Buffer.Data(), m_Buffer.Capacity(), &read_count);
+ result = Reader.Read(m_HeaderData.Data(), m_HeaderData.Capacity(), &read_count);
if ( ASDCP_FAILURE(result) )
{
- DefaultLogSink().Error("OPAtomHeader::InitFromFile, Read failed\n");
+ DefaultLogSink().Error("OP1aHeader::InitFromFile, Read failed\n");
return result;
}
- if ( read_count != m_Buffer.Capacity() )
+ if ( read_count != m_HeaderData.Capacity() )
{
DefaultLogSink().Error("Short read of OP-Atom header metadata; wanted %u, got %u\n",
- m_Buffer.Capacity(), read_count);
+ m_HeaderData.Capacity(), read_count);
return RESULT_KLV_CODING;
}
}
if ( ASDCP_SUCCESS(result) )
- result = InitFromBuffer(m_Buffer.RoData(), m_Buffer.Capacity());
+ result = InitFromBuffer(m_HeaderData.RoData(), m_HeaderData.Capacity());
return result;
}
//
ASDCP::Result_t
-ASDCP::MXF::OPAtomHeader::InitFromPartitionBuffer(const byte_t* p, ui32_t l)
+ASDCP::MXF::OP1aHeader::InitFromPartitionBuffer(const byte_t* p, ui32_t l)
{
Result_t result = KLVPacket::InitFromBuffer(p, l);
//
ASDCP::Result_t
-ASDCP::MXF::OPAtomHeader::InitFromBuffer(const byte_t* p, ui32_t l)
+ASDCP::MXF::OP1aHeader::InitFromBuffer(const byte_t* p, ui32_t l)
{
assert(m_Dict);
Result_t result = RESULT_OK;
}
ASDCP::Result_t
-ASDCP::MXF::OPAtomHeader::GetMDObjectByID(const UUID& ObjectID, InterchangeObject** Object)
+ASDCP::MXF::OP1aHeader::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)
+ASDCP::MXF::OP1aHeader::GetMDObjectByType(const byte_t* ObjectID, InterchangeObject** Object)
{
InterchangeObject* TmpObject;
//
ASDCP::Result_t
-ASDCP::MXF::OPAtomHeader::GetMDObjectsByType(const byte_t* ObjectID, std::list<InterchangeObject*>& ObjectList)
+ASDCP::MXF::OP1aHeader::GetMDObjectsByType(const byte_t* ObjectID, std::list<InterchangeObject*>& ObjectList)
{
return m_PacketList->GetMDObjectsByType(ObjectID, ObjectList);
}
//
ASDCP::MXF::Identification*
-ASDCP::MXF::OPAtomHeader::GetIdentification()
+ASDCP::MXF::OP1aHeader::GetIdentification()
{
InterchangeObject* Object;
//
ASDCP::MXF::SourcePackage*
-ASDCP::MXF::OPAtomHeader::GetSourcePackage()
+ASDCP::MXF::OP1aHeader::GetSourcePackage()
{
InterchangeObject* Object;
return 0;
}
-//
-ASDCP::MXF::RIP&
-ASDCP::MXF::OPAtomHeader::GetRIP() { return m_RIP; }
-
//
ASDCP::Result_t
-ASDCP::MXF::OPAtomHeader::WriteToFile(Kumu::FileWriter& Writer, ui32_t HeaderSize)
+ASDCP::MXF::OP1aHeader::WriteToFile(Kumu::FileWriter& Writer, ui32_t HeaderSize)
{
assert(m_Dict);
if ( m_Preface == 0 )
//
void
-ASDCP::MXF::OPAtomHeader::Dump(FILE* stream)
+ASDCP::MXF::OP1aHeader::Dump(FILE* stream)
{
if ( stream == 0 )
stream = stderr;
{
Result_t result = Partition::InitFromFile(Reader); // test UL and OP
- // slurp up the remainder of the footer
- ui32_t read_count = 0;
+ // slurp up the remainder of the footer
+ ui32_t read_count = 0;
- if ( ASDCP_SUCCESS(result) )
+ if ( ASDCP_SUCCESS(result) )
{
- assert (IndexByteCount <= 0xFFFFFFFFL);
- // At this point, m_Buffer may not have been initialized
- // so it's capacity is zero and data pointer is NULL
- // However, if IndexByteCount is zero then the capacity
- // doesn't change and the data pointer is not set.
- result = m_Buffer.Capacity((ui32_t) IndexByteCount);
+ assert (IndexByteCount <= 0xFFFFFFFFL);
+ // At this point, m_FooterData may not have been initialized
+ // so it's capacity is zero and data pointer is NULL
+ // However, if IndexByteCount is zero then the capacity
+ // doesn't change and the data pointer is not set.
+ result = m_FooterData.Capacity((ui32_t) IndexByteCount);
}
- if ( ASDCP_SUCCESS(result) && m_Buffer.Data() )
- result = Reader.Read(m_Buffer.Data(), m_Buffer.Capacity(), &read_count);
+ if ( ASDCP_SUCCESS(result) && m_FooterData.Data() )
+ result = Reader.Read(m_FooterData.Data(), m_FooterData.Capacity(), &read_count);
- if ( ASDCP_SUCCESS(result) && read_count != m_Buffer.Capacity() )
+ if ( ASDCP_SUCCESS(result) && read_count != m_FooterData.Capacity() )
{
DefaultLogSink().Error("Short read of footer partition: got %u, expecting %u\n",
- read_count, m_Buffer.Capacity());
+ read_count, m_FooterData.Capacity());
+ return RESULT_FAIL;
+ }
+ else if( ASDCP_SUCCESS(result) && !m_FooterData.Data() )
+ {
+ DefaultLogSink().Error( "Buffer for footer partition not created: IndexByteCount = %u\n",
+ IndexByteCount );
return RESULT_FAIL;
}
- else if( ASDCP_SUCCESS(result) && !m_Buffer.Data() )
- {
- DefaultLogSink().Error( "Buffer for footer partition not created: IndexByteCount = %u\n",
- IndexByteCount );
- return RESULT_FAIL;
- }
if ( ASDCP_SUCCESS(result) )
- result = InitFromBuffer(m_Buffer.RoData(), m_Buffer.Capacity());
-
+ result = InitFromBuffer(m_FooterData.RoData(), m_FooterData.Capacity());
+
return result;
}
/*
-Copyright (c) 2005-2012, John Hurst
+Copyright (c) 2005-2013, John Hurst
All rights reserved.
Redistribution and use in source and binary forms, with or without
class SourcePackage;
//
- class OPAtomHeader : public Partition
+ class OP1aHeader : public Partition
{
- ASDCP_NO_COPY_CONSTRUCT(OPAtomHeader);
- OPAtomHeader();
+ Kumu::ByteString m_HeaderData;
+ ASDCP_NO_COPY_CONSTRUCT(OP1aHeader);
+ OP1aHeader();
public:
- const Dictionary*& m_Dict;
- ASDCP::MXF::RIP m_RIP;
+ const Dictionary*& m_Dict;
ASDCP::MXF::Primer m_Primer;
Preface* m_Preface;
- ASDCP::FrameBuffer m_Buffer;
- bool m_HasRIP;
- OPAtomHeader(const Dictionary*&);
- virtual ~OPAtomHeader();
+ OP1aHeader(const Dictionary*&);
+ virtual ~OP1aHeader();
virtual Result_t InitFromFile(const Kumu::FileReader& Reader);
virtual Result_t InitFromPartitionBuffer(const byte_t* p, ui32_t l);
virtual Result_t InitFromBuffer(const byte_t* p, ui32_t l);
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);
- virtual ASDCP::MXF::RIP& GetRIP();
Identification* GetIdentification();
SourcePackage* GetSourcePackage();
};
//
class OPAtomIndexFooter : public Partition
{
+ Kumu::ByteString m_FooterData;
IndexTableSegment* m_CurrentSegment;
- ASDCP::FrameBuffer m_Buffer;
ui32_t m_BytesPerEditUnit;
Rational m_EditRate;
ui32_t m_BodySID;
virtual void SetIndexParamsVBR(IPrimerLookup* lookup, const Rational& Rate, Kumu::fpos_t offset);
};
+
} // namespace MXF
} // namespace ASDCP
## Makefile.am -- Process this file with automake to produce Makefile.in
#
# $Id$
-# Copyright (c) 2007-2011 John Hurst. All rights reserved.
+#
+# Copyright (c) 2007-2013 John Hurst. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ACLOCAL_AMFLAGS = -I m4
+
# Allow for configure's changes to this makefile
AM_CPPFLAGS =
AM_LDFLAGS =
Wav.h \
PCMParserList.h \
AtmosSyncChannel_Generator.h
+
nodist_include_HEADERS = TimedText_Transform.h
endif
+if AS_02_USE
+include_HEADERS += AS_02.h
+endif
+
# list of the libraries to build and install
+
lib_LTLIBRARIES = libkumu.la libasdcp.la
+if AS_02_USE
+lib_LTLIBRARIES += libas02.la
+endif
+
# sources for kumu library
libkumu_la_SOURCES = KM_error.h KM_fileio.cpp KM_fileio.h KM_log.cpp KM_log.h \
KM_memio.h KM_mutex.h KM_platform.h KM_prng.cpp KM_prng.h KM_util.cpp \
SyncEncoder.c SyncEncoder.h SyncCommon.h CRC16.c CRC16.h \
UUIDInformation.c UUIDInformation.h
-
if DEV_HEADERS
nodist_libasdcp_la_SOURCES += TimedText_Transform.h TimedText_Transform.cpp
endif
libasdcp_la_LIBADD = libkumu.la
libasdcp_la_CPPFLAGS = -DASDCP_PLATFORM=\"@host@\"
+if AS_02_USE
+# sources for as-02 library
+libas02_la_SOURCES = \
+ AS_02.h \
+ AS_02_MXF.cpp \
+ AS_02_JP2K.cpp \
+ AS_02_PCM.cpp \
+ h__02_Reader.cpp \
+ h__02_Writer.cpp \
+ AS_02_internal.h
+
+libas02_la_LDFLAGS = -release @VERSION@
+libas02_la_LIBADD = libasdcp.la libkumu.la
+libas02_la_CPPFLAGS = -DASDCP_PLATFORM=\"@host@\"
+endif
+
# Python extension
if PYTHON_USE
lib_LTLIBRARIES += libpyasdcp.la
j2c-test blackwave klvwalk wavesplit \
kmfilegen kmrandgen kmuuidgen
+if AS_02_USE
+bin_PROGRAMS += \
+ as-02-wrap \
+ as-02-unwrap
+endif
+
+
# sources and linkage for CLI utilities
asdcp_test_SOURCES = asdcp-test.cpp
asdcp_test_LDADD = libasdcp.la
j2c_test_SOURCES = j2c-test.cpp
j2c_test_LDADD = libasdcp.la
+if AS_02_USE
+as_02_wrap_SOURCES = as-02-wrap.cpp
+as_02_wrap_LDADD = libas02.la
+
+as_02_unwrap_SOURCES = as-02-unwrap.cpp
+as_02_unwrap_LDADD = libas02.la
+endif
+
# list of programs that need to be compiled for use in test suite
check_PROGRAMS = asdcp-mem-test path-test \
fips-186-rng-test asdcp-version
while ( ASDCP_SUCCESS(result) && duration++ < Options.duration )
{
- if ( duration == 1 )
+ result = Parser.ReadFrame(FrameBuffer);
+
+ if ( ASDCP_SUCCESS(result) )
{
- result = Parser.ReadFrame(FrameBuffer);
-
- if ( ASDCP_SUCCESS(result) )
- {
- if ( Options.verbose_flag )
- FrameBuffer.Dump(stderr, Options.fb_dump_size);
-
- if ( Options.encrypt_header_flag )
- FrameBuffer.PlaintextOffset(0);
- }
+ if ( Options.verbose_flag )
+ FrameBuffer.Dump(stderr, Options.fb_dump_size);
+
+ if ( Options.encrypt_header_flag )
+ FrameBuffer.PlaintextOffset(0);
}
if ( ASDCP_SUCCESS(result) && ! Options.no_write_flag )
if ( ASDCP_SUCCESS(result) && Options.channel_assignment.HasValue() )
{
MXF::WaveAudioDescriptor *descriptor = 0;
- Writer.OPAtomHeader().GetMDObjectByType(DefaultSMPTEDict().ul(MDD_WaveAudioDescriptor),
- reinterpret_cast<MXF::InterchangeObject**>(&descriptor));
+ Writer.OP1aHeader().GetMDObjectByType(DefaultSMPTEDict().ul(MDD_WaveAudioDescriptor),
+ reinterpret_cast<MXF::InterchangeObject**>(&descriptor));
descriptor->ChannelAssignment = Options.channel_assignment;
}
}
const Dictionary& Dict = DefaultCompositeDict();
MXF::RGBAEssenceDescriptor *descriptor = 0;
- Result_t result = m_Reader.OPAtomHeader().GetMDObjectByType(DefaultCompositeDict().ul(MDD_RGBAEssenceDescriptor),
- reinterpret_cast<MXF::InterchangeObject**>(&descriptor));
+ Result_t result = m_Reader.OP1aHeader().GetMDObjectByType(DefaultCompositeDict().ul(MDD_RGBAEssenceDescriptor),
+ reinterpret_cast<MXF::InterchangeObject**>(&descriptor));
if ( KM_SUCCESS(result) )
m_PictureEssenceCoding = descriptor->PictureEssenceCoding;
const Dictionary& Dict = DefaultCompositeDict();
MXF::WaveAudioDescriptor *descriptor = 0;
- Result_t result = m_Reader.OPAtomHeader().GetMDObjectByType(DefaultCompositeDict().ul(MDD_WaveAudioDescriptor),
- reinterpret_cast<MXF::InterchangeObject**>(&descriptor));
+ Result_t result = m_Reader.OP1aHeader().GetMDObjectByType(DefaultCompositeDict().ul(MDD_WaveAudioDescriptor),
+ reinterpret_cast<MXF::InterchangeObject**>(&descriptor));
if ( KM_SUCCESS(result) )
{
fprintf(stderr, "File is not AS-DCP: %s\n", Options.filenames.front().c_str());
Kumu::FileReader Reader;
const Dictionary* Dict = &DefaultCompositeDict();
- MXF::OPAtomHeader TestHeader(Dict);
+ MXF::OP1aHeader TestHeader(Dict);
result = Reader.OpenRead(Options.filenames.front().c_str());
{
const Dictionary* Dict = &DefaultCompositeDict();
PCM::MXFReader Reader;
- MXF::OPAtomHeader OPAtomHeader(Dict);
+ MXF::OP1aHeader Header(Dict);
MXF::WaveAudioDescriptor *descriptor = 0;
result = Reader.OpenRead(Options.filenames[0]);
if ( ASDCP_SUCCESS(result) )
- result = Reader.OPAtomHeader().GetMDObjectByType(Dict->ul(MDD_WaveAudioDescriptor), reinterpret_cast<MXF::InterchangeObject**>(&descriptor));
+ result = Reader.OP1aHeader().GetMDObjectByType(Dict->ul(MDD_WaveAudioDescriptor), reinterpret_cast<MXF::InterchangeObject**>(&descriptor));
if ( ASDCP_SUCCESS(result) )
{
fprintf(stderr, "File is not AS-DCP: %s\n", Options.filenames[0]);
Kumu::FileReader Reader;
const Dictionary* Dict = &DefaultCompositeDict();
- MXF::OPAtomHeader TestHeader(Dict);
+ MXF::OP1aHeader TestHeader(Dict);
result = Reader.OpenRead(Options.filenames[0]);
if ( ASDCP_SUCCESS(result) && Options.picture_coding.HasValue() )
{
MXF::RGBAEssenceDescriptor *descriptor = 0;
- Writer.OPAtomHeader().GetMDObjectByType(DefaultSMPTEDict().ul(MDD_RGBAEssenceDescriptor),
- reinterpret_cast<MXF::InterchangeObject**>(&descriptor));
+ Writer.OP1aHeader().GetMDObjectByType(DefaultSMPTEDict().ul(MDD_RGBAEssenceDescriptor),
+ reinterpret_cast<MXF::InterchangeObject**>(&descriptor));
descriptor->PictureEssenceCoding = Options.picture_coding;
}
}
if ( ASDCP_SUCCESS(result) && Options.picture_coding.HasValue() )
{
MXF::RGBAEssenceDescriptor *descriptor = 0;
- Writer.OPAtomHeader().GetMDObjectByType(DefaultSMPTEDict().ul(MDD_RGBAEssenceDescriptor),
- reinterpret_cast<MXF::InterchangeObject**>(&descriptor));
+ Writer.OP1aHeader().GetMDObjectByType(DefaultSMPTEDict().ul(MDD_RGBAEssenceDescriptor),
+ reinterpret_cast<MXF::InterchangeObject**>(&descriptor));
descriptor->PictureEssenceCoding = Options.picture_coding;
}
}
if ( ASDCP_SUCCESS(result) && Options.channel_assignment.HasValue() )
{
MXF::WaveAudioDescriptor *descriptor = 0;
- Writer.OPAtomHeader().GetMDObjectByType(DefaultSMPTEDict().ul(MDD_WaveAudioDescriptor),
- reinterpret_cast<MXF::InterchangeObject**>(&descriptor));
+ Writer.OP1aHeader().GetMDObjectByType(DefaultSMPTEDict().ul(MDD_WaveAudioDescriptor),
+ reinterpret_cast<MXF::InterchangeObject**>(&descriptor));
descriptor->ChannelAssignment = Options.channel_assignment;
}
}
/*
- Copyright (c) 2011-2012, Robert Scheler, Heiko Sparenberg Fraunhofer IIS, John Hurst
+ Copyright (c) 2011-2013, Robert Scheler, Heiko Sparenberg Fraunhofer IIS, John Hurst
All rights reserved.
Redistribution and use in source and binary forms, with or without
using namespace ASDCP;
using namespace ASDCP::MXF;
+
+static Kumu::Mutex sg_DefaultMDInitLock;
+static bool sg_DefaultMDTypesInit = false;
+static const ASDCP::Dictionary *sg_dict;
+
+//
+void
+AS_02::default_md_object_init()
+{
+ if ( ! sg_DefaultMDTypesInit )
+ {
+ Kumu::AutoMutex BlockLock(sg_DefaultMDInitLock);
+
+ if ( ! sg_DefaultMDTypesInit )
+ {
+ sg_dict = &DefaultSMPTEDict();
+ g_AS02IndexReader = new AS_02::MXF::AS02IndexReader(sg_dict);
+ sg_DefaultMDTypesInit = true;
+ }
+ }
+}
+
+
+
+
+AS_02::h__AS02Reader::h__AS02Reader(const ASDCP::Dictionary& d) : ASDCP::MXF::TrackFileReader<ASDCP::MXF::OP1aHeader, AS_02::MXF::AS02IndexReader>(d) {}
+AS_02::h__AS02Reader::~h__AS02Reader() {}
+
+
+#if 0
//
-AS_02::h__Reader::h__Reader(const Dictionary& d) :
- m_HeaderPart(m_Dict), m_FooterPart(m_Dict), m_Dict(&d), m_EssenceStart(0)
+AS_02::h__AS02Reader::h__Reader(const Dictionary& d) :
+ m_HeaderPart(m_Dict), m_IndexAccess(m_Dict), m_Dict(&d), m_EssenceStart(0)
{
m_pCurrentIndexPartition = 0;
//// start_pos = 0;
}
-AS_02::h__Reader::~h__Reader()
+AS_02::h__AS02Reader::~h__Reader()
{
std::vector<Partition*>::iterator bli = m_BodyPartList.begin();
for ( ; bli != m_BodyPartList.end(); bli++ ){
}
Close();
}
-
-void
-AS_02::h__Reader::Close()
-{
- m_File.Close();
-}
+#endif
//------------------------------------------------------------------------------------------
//
-//
-Result_t
-AS_02::h__Reader::InitInfo()
-{
- assert(m_Dict);
- InterchangeObject* Object;
-
- UL OPAtomUL(SMPTE_390_OPAtom_Entry().ul);
- UL Interop_OPAtomUL(MXFInterop_OPAtom_Entry().ul);
- m_Info.LabelSetType = LS_MXF_SMPTE;
-
- // Identification
- Result_t result = m_HeaderPart.GetMDObjectByType(OBJ_TYPE_ARGS(Identification), &Object);
-
- if( ASDCP_SUCCESS(result) )
- MD_to_WriterInfo((Identification*)Object, m_Info);
-
- // SourcePackage
- if( ASDCP_SUCCESS(result) )
- result = m_HeaderPart.GetMDObjectByType(OBJ_TYPE_ARGS(SourcePackage), &Object);
-
- if( ASDCP_SUCCESS(result) )
- {
- SourcePackage* SP = (SourcePackage*)Object;
- memcpy(m_Info.AssetUUID, SP->PackageUID.Value() + 16, UUIDlen);
- }
-
- // optional CryptographicContext
- if( ASDCP_SUCCESS(result) )
- {
- Result_t cr_result = m_HeaderPart.GetMDObjectByType(OBJ_TYPE_ARGS(CryptographicContext), &Object);
-
- if( ASDCP_SUCCESS(cr_result) )
- MD_to_CryptoInfo((CryptographicContext*)Object, m_Info, *m_Dict);
- }
-
- return result;
-}
-
-// standard method of populating the in-memory index
-Result_t
-AS_02::h__Reader::InitMXFIndex()
-{
- if ( ! m_File.IsOpen() )
- return RESULT_INIT;
-
- Result_t result = m_File.Seek(m_HeaderPart.FooterPartition);
-
- if ( ASDCP_SUCCESS(result) )
- {
- m_FooterPart.m_Lookup = &m_HeaderPart.m_Primer;
- //Footer don't need to be initialized because there is no index table in the footer
- //result = m_FooterPart.InitFromFile(m_File);
- }
-
- if ( ASDCP_SUCCESS(result) )
- m_File.Seek(m_EssenceStart);
-
- return result;
-}
-
-
//
// end h__02_Reader.cpp
//
/*
- Copyright (c) 2011-2012, Robert Scheler, Heiko Sparenberg Fraunhofer IIS, John Hurst
+ Copyright (c) 2011-2013, Robert Scheler, Heiko Sparenberg Fraunhofer IIS, John Hurst
All rights reserved.
Redistribution and use in source and binary forms, with or without
using namespace ASDCP;
using namespace ASDCP::MXF;
-// a magic number identifying asdcplib
-#ifndef ASDCP_BUILD_NUMBER
-#define ASDCP_BUILD_NUMBER 0x6A68
-#endif
//
-AS_02::h__Writer::h__Writer(const Dictionary& d) :
- m_HeaderPart(m_Dict), m_FooterPart(m_Dict), m_Dict(&d),
- m_HeaderSize(0), m_EssenceStart(0),
- m_EssenceDescriptor(0), m_FramesWritten(0),
- m_StreamOffset(0), m_BodyOffset(0),
- m_CurrentBodySID(0), m_CurrentIndexSID(0),
- m_PartitionSpace(60), m_IndexStrategy(AS_02::IS_FOLLOW)
-{
-}
-
-AS_02::h__Writer::~h__Writer()
-{
- while (! m_BodyPartList.empty() )
- {
- delete m_BodyPartList.back();
- m_BodyPartList.pop_back();
- }
-}
-
-//
-void
-AS_02::h__Writer::InitHeader()
-{
- assert(m_Dict);
- assert(m_EssenceDescriptor);
-
- m_HeaderPart.m_Primer.ClearTagList();
- m_HeaderPart.m_Preface = new Preface(m_Dict);
- m_HeaderPart.AddChildObject(m_HeaderPart.m_Preface);
-
- // Set the Operational Pattern label -- we're just starting and have no RIP or index,
- // so we tell the world by using OP1a
- m_HeaderPart.m_Preface->OperationalPattern = UL(m_Dict->ul(MDD_OP1a));
- m_HeaderPart.OperationalPattern = m_HeaderPart.m_Preface->OperationalPattern;
-
- //always more than 3 partition in AS-02; essence is not permitted to be existent in the header
- m_HeaderPart.m_RIP.PairArray.push_back(RIP::Pair(0, 0)); // no essence in header
-
- //
- // Identification
- //
- Identification* Ident = new Identification(m_Dict);
- m_HeaderPart.AddChildObject(Ident);
- m_HeaderPart.m_Preface->Identifications.push_back(Ident->InstanceUID);
-
- Kumu::GenRandomValue(Ident->ThisGenerationUID);
- Ident->CompanyName = m_Info.CompanyName.c_str();
- Ident->ProductName = m_Info.ProductName.c_str();
- Ident->VersionString = m_Info.ProductVersion.c_str();
- Ident->ProductUID.Set(m_Info.ProductUUID);
- Ident->Platform = ASDCP_PLATFORM;
-
- std::vector<int> version = version_split(Version());
-
- Ident->ToolkitVersion.Major = version[0];
- Ident->ToolkitVersion.Minor = version[1];
- Ident->ToolkitVersion.Patch = version[2];
- 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, const Dictionary*& Dict)
-{
- TrackSet<ClipT> NewTrack;
-
- NewTrack.Track = new Track(Dict);
- 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(Dict);
- 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, const Dictionary*& Dict)
-{
- assert(Dict);
- UL TCUL(Dict->ul(MDD_TimecodeDataDef));
-
- TrackSet<TimecodeComponent> NewTrack = CreateTrackAndSequence<PackageT, TimecodeComponent>(Header, Package, "Timecode Track", EditRate, TCUL, 1, Dict);
-
- NewTrack.Clip = new TimecodeComponent(Dict);
- 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
-AS_02::h__Writer::AddSourceClip(const ASDCP::MXF::Rational& EditRate, ui32_t TCFrameRate,
- const std::string& TrackName, const UL& EssenceUL,
- const UL& DataDefinition, const std::string& PackageLabel)
-{
- //
- ContentStorage* Storage = new ContentStorage(m_Dict);
- m_HeaderPart.AddChildObject(Storage);
- m_HeaderPart.m_Preface->ContentStorage = Storage->InstanceUID;
-
- EssenceContainerData* ECD = new EssenceContainerData(m_Dict);
- m_HeaderPart.AddChildObject(ECD);
- Storage->EssenceContainerData.push_back(ECD->InstanceUID);
- 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
- //
- m_MaterialPackage = new MaterialPackage(m_Dict);
- m_MaterialPackage->Name = "AS_02 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_Dict);
- m_DurationUpdateList.push_back(&(MPTCTrack.Sequence->Duration));
- m_DurationUpdateList.push_back(&(MPTCTrack.Clip->Duration));
-
- TrackSet<SourceClip> MPTrack =
- CreateTrackAndSequence<MaterialPackage, SourceClip>(m_HeaderPart, *m_MaterialPackage,
- TrackName, EditRate, DataDefinition,
- 2, m_Dict);
- m_DurationUpdateList.push_back(&(MPTrack.Sequence->Duration));
-
- MPTrack.Clip = new SourceClip(m_Dict);
- 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_Dict);
- 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_Dict);
- 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_Dict);
- m_DurationUpdateList.push_back(&(FPTrack.Sequence->Duration));
-
- // Consult ST 379:2004 Sec. 6.3, "Element to track relationship" to see where "12" comes from.
- FPTrack.Track->TrackNumber = KM_i32_BE(Kumu::cp2i<ui32_t>((EssenceUL.Value() + 12)));
-
- FPTrack.Clip = new SourceClip(m_Dict);
- 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
-AS_02::h__Writer::AddDMSegment(const ASDCP::MXF::Rational& EditRate, ui32_t TCFrameRate,
- const std::string& TrackName, const UL& DataDefinition,
- const std::string& PackageLabel)
-{
- //
- ContentStorage* Storage = new ContentStorage(m_Dict);
- m_HeaderPart.AddChildObject(Storage);
- m_HeaderPart.m_Preface->ContentStorage = Storage->InstanceUID;
-
- EssenceContainerData* ECD = new EssenceContainerData(m_Dict);
- m_HeaderPart.AddChildObject(ECD);
- Storage->EssenceContainerData.push_back(ECD->InstanceUID);
- 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
- //
- m_MaterialPackage = new MaterialPackage(m_Dict);
- m_MaterialPackage->Name = "AS_02 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_Dict);
- 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_Dict);
- m_DurationUpdateList.push_back(&(MPTrack.Sequence->Duration));
-
- MPTrack.Clip = new DMSegment(m_Dict);
- 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_Dict);
- 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_Dict);
- m_DurationUpdateList.push_back(&(FPTCTrack.Sequence->Duration));
- m_DurationUpdateList.push_back(&(FPTCTrack.Clip->Duration));
-
- TrackSet<DMSegment> FPTrack =
- CreateTrackAndSequence<SourcePackage, DMSegment>(m_HeaderPart, *m_FilePackage,
- TrackName, EditRate, DataDefinition,
- 2, m_Dict);
- m_DurationUpdateList.push_back(&(FPTrack.Sequence->Duration));
-
- FPTrack.Clip = new DMSegment(m_Dict);
- 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
-AS_02::h__Writer::AddEssenceDescriptor(const UL& WrappingUL)
-{
- //
- // Essence Descriptor
- //
- m_EssenceDescriptor->EssenceContainer = WrappingUL;
- m_HeaderPart.m_Preface->PrimaryPackage = m_FilePackage->InstanceUID;
-
- //
- // Essence Descriptors
- //
- assert(m_Dict);
- //TODO: Mono Essence, only one GenericContainer ?
- //UL GenericContainerUL(m_Dict->ul(MDD_GCMulti));
- //m_HeaderPart.EssenceContainers.push_back(GenericContainerUL);
-
- if ( m_Info.EncryptedEssence )
- {
- UL CryptEssenceUL(m_Dict->ul(MDD_EncryptedContainerLabel));
- m_HeaderPart.EssenceContainers.push_back(CryptEssenceUL);
- m_HeaderPart.m_Preface->DMSchemes.push_back(UL(m_Dict->ul(MDD_CryptographicFrameworkLabel)));
- AddDMScrypt(m_HeaderPart, *m_FilePackage, m_Info, WrappingUL, m_Dict);
- }
- else
- {
- m_HeaderPart.EssenceContainers.push_back(WrappingUL);
- }
-
- m_HeaderPart.m_Preface->EssenceContainers = m_HeaderPart.EssenceContainers;
- m_HeaderPart.AddChildObject(m_EssenceDescriptor);
-
- std::list<InterchangeObject*>::iterator sdli = m_EssenceSubDescriptorList.begin();
- for ( ; sdli != m_EssenceSubDescriptorList.end(); sdli++ )
- m_HeaderPart.AddChildObject(*sdli);
-
- m_FilePackage->Descriptor = m_EssenceDescriptor->InstanceUID;
-}
-
-//
-Result_t
-AS_02::h__Writer::CreateBodyPart(const ASDCP::MXF::Rational& EditRate, ui32_t BytesPerEditUnit)
-{
- assert(m_Dict);
- Result_t result = RESULT_OK;
- m_EditRate = EditRate;
- m_BytesPerEditUnit = BytesPerEditUnit;
-
- result = CreateBodyPartPair();
-
- //TODO: no IndexTables in the footer -> The spec is silent on that topic
- m_FooterPart.IndexSID = 0;//129;
-
- return result;
-}
-
-// standard method of creating a new BodyPartition Pair for Essence and IndexTables
-Result_t AS_02::h__Writer::CreateBodyPartPair()
-{
- Result_t result = RESULT_OK;
-
- if ( m_IndexStrategy == AS_02::IS_FILE_SPECIFIC ){
- result = RESULT_FAIL;
- }
-
- //similar to both index strategies
-
- Partition *m_BodyPartEssence = new ASDCP::MXF::Partition(m_Dict);
- m_BodyPartEssence->EssenceContainers = m_HeaderPart.EssenceContainers;
- //necessary? - here we must increment the BodySID, when a new BodyPartion is created
- m_BodyPartEssence->BodySID = 1;//++m_CurrentBodySID;
- UL OperationalPattern(m_Dict->ul(MDD_OP1a));
- m_BodyPartEssence->OperationalPattern = OperationalPattern;
-
- m_BodyPartEssence->FooterPartition = 0;
- m_BodyPartEssence->IndexSID = 0;
- m_BodyPartEssence->BodyOffset = m_BodyOffset;
-
- m_CurrentIndexBodyPartition = new AS_02::MXF::OP1aIndexBodyPartion(this->m_Dict);
- m_CurrentIndexBodyPartition->EssenceContainers = m_HeaderPart.EssenceContainers;
- m_CurrentIndexBodyPartition->BodySID = 0;
- m_CurrentIndexBodyPartition->OperationalPattern = OperationalPattern;
- m_CurrentIndexBodyPartition->FooterPartition = 0;
- m_CurrentIndexBodyPartition->IndexSID = 129;//++m_CurrentIndexSID;
-
- //we must differentiate between index_strategy "lead" and "follow"
- if ( m_IndexStrategy == AS_02::IS_FOLLOW )
- {
- if(m_BodyPartList.size()>0){
- m_BodyPartEssence->PreviousPartition = m_BodyPartList.back()->ThisPartition;
- }
- else{
- m_BodyPartEssence->PreviousPartition = m_HeaderPart.ThisPartition;
- }
- /* Write partition header for the body partition and create IndexBodyPartition.
- When "all" essence packets are written, write out index table. */
- m_CurrentIndexBodyPartition->ThisPartition = 0;
- m_BodyPartEssence->ThisPartition = m_File.Tell();
- m_CurrentIndexBodyPartition->PreviousPartition = m_BodyPartEssence->ThisPartition;\r
- m_HeaderPart.m_RIP.PairArray.push_back(RIP::Pair(m_CurrentIndexBodyPartition->BodySID, m_CurrentIndexBodyPartition->ThisPartition));
-
- this->m_BodyPartList.push_back(m_CurrentIndexBodyPartition);
- this->m_BodyPartList.push_back(m_BodyPartEssence);
- }
- else if ( m_IndexStrategy == AS_02::IS_LEAD )
- {
- /* Write KLVFill packet large enough to hold the completed index data */
- m_CurrentIndexBodyPartition->ThisPartition = m_File.Tell();
- m_CurrentIndexBodyPartition->FillWriteToFile(m_File,m_PartitionSpace);
- m_BodyPartEssence->ThisPartition = m_File.Tell();
- m_BodyPartEssence->PreviousPartition = m_CurrentIndexBodyPartition->ThisPartition;\r
- m_HeaderPart.m_RIP.PairArray.push_back(RIP::Pair(m_CurrentIndexBodyPartition->BodySID, m_CurrentIndexBodyPartition->ThisPartition));
-
- if(m_BodyPartList.size()>0)
- {
- m_CurrentIndexBodyPartition->PreviousPartition = m_BodyPartList.back()->ThisPartition;
- }
- else
- {
- m_CurrentIndexBodyPartition->PreviousPartition = m_HeaderPart.ThisPartition;
- }
-
- //necessary to traverse across all of the body partition packs and update the FooterPartition entries at the end of writing
- this->m_BodyPartList.push_back(m_CurrentIndexBodyPartition);
- this->m_BodyPartList.push_back(m_BodyPartEssence);
- }
-
- /* similar to both index strategies */
-
- m_HeaderPart.m_RIP.PairArray.push_back(RIP::Pair(m_BodyPartEssence->BodySID, m_BodyPartEssence->ThisPartition));
- UL BodyUL(m_Dict->ul(MDD_ClosedCompleteBodyPartition));
- result = m_BodyPartEssence->WriteToFile(m_File, BodyUL);
-
- if ( ASDCP_SUCCESS(result) )
- {
- //TODO: Is this necessary?What means ECoffset?Never used in the code? If necessary check if it is set correctly.
-
- // Index setup
- Kumu::fpos_t ECoffset = m_File.Tell();
-
- if(m_BytesPerEditUnit == 0){
- m_CurrentIndexBodyPartition->SetIndexParamsVBR(&m_HeaderPart.m_Primer, m_EditRate, ECoffset);
- }
- else{
- m_CurrentIndexBodyPartition->SetIndexParamsCBR(&m_HeaderPart.m_Primer, m_BytesPerEditUnit, m_EditRate);
- }
- }
-
- return result;
-}
-
-Result_t AS_02::h__Writer::CompleteIndexBodyPart()
-{
- Result_t result = RESULT_OK;
- if ( m_IndexStrategy == AS_02::IS_FOLLOW )
- {\r
- m_CurrentIndexBodyPartition->ThisPartition = m_File.Tell();\r
- m_HeaderPart.m_RIP.PairArray.push_back(RIP::Pair(m_CurrentIndexBodyPartition->BodySID, m_CurrentIndexBodyPartition->ThisPartition));\r
- }
-
- UL BodyUL(m_Dict->ul(MDD_ClosedCompleteBodyPartition));\r
- ui64_t cur_pos = m_File.Tell();\r
- m_File.Seek(m_CurrentIndexBodyPartition->ThisPartition);\r
- result = m_CurrentIndexBodyPartition->WriteToFile(m_File, BodyUL);
- m_File.Seek(cur_pos);
- return result;
-}
+AS_02::h__AS02Writer::h__AS02Writer(const ASDCP::Dictionary& d) : ASDCP::MXF::TrackFileWriter<ASDCP::MXF::OP1aHeader>(d) {}
+AS_02::h__AS02Writer::~h__AS02Writer() {}
//
Result_t
-AS_02::h__Writer::WriteMXFHeader(const std::string& PackageLabel, const UL& WrappingUL,
- const std::string& TrackName, const UL& EssenceUL, const UL& DataDefinition,
- const ASDCP::MXF::Rational& EditRate, ui32_t TCFrameRate, ui32_t BytesPerEditUnit)
+AS_02::h__AS02Writer::WriteAS02Header(const std::string& PackageLabel, const ASDCP::UL& WrappingUL,
+ const std::string& TrackName, const ASDCP::UL& EssenceUL,
+ const ASDCP::UL& DataDefinition, const ASDCP::Rational& EditRate,
+ ui32_t TCFrameRate, ui32_t BytesPerEditUnit)
{
InitHeader();
AddSourceClip(EditRate, TCFrameRate, TrackName, EssenceUL, DataDefinition, PackageLabel);
Result_t result = m_HeaderPart.WriteToFile(m_File, m_HeaderSize);
//use the FrameRate for the indexing; initialize the SID counters
- m_CurrentBodySID = 0;
- m_CurrentIndexSID = 0;
+ /// m_CurrentBodySID = 0;
+ /// m_CurrentIndexSID = 0;
m_PartitionSpace = m_PartitionSpace * TCFrameRate; ///// TODO ????
- if ( KM_SUCCESS(result) )
- result = CreateBodyPart(EditRate, BytesPerEditUnit);
-
- return result;
-}
-
-
-// standard method of writing a plaintext or encrypted frame
-Result_t
-AS_02::h__Writer::WriteEKLVPacket(const ASDCP::FrameBuffer& FrameBuf, const byte_t* EssenceUL,
- AESEncContext* Ctx, HMACContext* HMAC)
-{
- Result_t result = RESULT_OK;
- IntegrityPack IntPack;
-
- byte_t overhead[128];
- Kumu::MemIOWriter Overhead(overhead, 128);
- assert(m_Dict);
-
- if ( FrameBuf.Size() == 0 )
- {
- DefaultLogSink().Error("Cannot write empty frame buffer\n");
- return RESULT_EMPTY_FB;
- }
-
- if ( m_Info.EncryptedEssence )
- {
- if ( ! Ctx )
- return RESULT_CRYPT_CTX;
-
- if ( m_Info.UsesHMAC && ! HMAC )
- return RESULT_HMAC_CTX;
-
- if ( FrameBuf.PlaintextOffset() > FrameBuf.Size() )
- return RESULT_LARGE_PTO;
-
- // encrypt the essence data (create encrypted source value)
- result = EncryptFrameBuffer(FrameBuf, m_CtFrameBuf, Ctx);
-
- // create HMAC
- if ( ASDCP_SUCCESS(result) && m_Info.UsesHMAC )
- result = IntPack.CalcValues(m_CtFrameBuf, m_Info.AssetUUID, m_FramesWritten + 1, HMAC);
-
- if ( ASDCP_SUCCESS(result) )
- { // write UL
- Overhead.WriteRaw(m_Dict->ul(MDD_CryptEssence), SMPTE_UL_LENGTH);
-
- // construct encrypted triplet header
- ui32_t ETLength = klv_cryptinfo_size + m_CtFrameBuf.Size();
- ui32_t BER_length = MXF_BER_LENGTH;
-
- if ( m_Info.UsesHMAC )
- ETLength += klv_intpack_size;
- else
- ETLength += (MXF_BER_LENGTH * 3); // for empty intpack
-
- if ( ETLength > 0x00ffffff ) // Need BER integer longer than MXF_BER_LENGTH bytes
- {
- BER_length = Kumu::get_BER_length_for_value(ETLength);
-
- // the packet is longer by the difference in expected vs. actual BER length
- ETLength += BER_length - MXF_BER_LENGTH;
-
- if ( BER_length == 0 )
- result = RESULT_KLV_CODING;
- }
-
- if ( ASDCP_SUCCESS(result) )
- {
- if ( ! ( Overhead.WriteBER(ETLength, BER_length) // write encrypted triplet length
- && Overhead.WriteBER(UUIDlen, MXF_BER_LENGTH) // write ContextID length
- && Overhead.WriteRaw(m_Info.ContextID, UUIDlen) // write ContextID
- && Overhead.WriteBER(sizeof(ui64_t), MXF_BER_LENGTH) // write PlaintextOffset length
- && Overhead.WriteUi64BE(FrameBuf.PlaintextOffset()) // write PlaintextOffset
- && Overhead.WriteBER(SMPTE_UL_LENGTH, MXF_BER_LENGTH) // write essence UL length
- && Overhead.WriteRaw((byte_t*)EssenceUL, SMPTE_UL_LENGTH) // write the essence UL
- && Overhead.WriteBER(sizeof(ui64_t), MXF_BER_LENGTH) // write SourceLength length
- && Overhead.WriteUi64BE(FrameBuf.Size()) // write SourceLength
- && Overhead.WriteBER(m_CtFrameBuf.Size(), BER_length) ) ) // write ESV length
- {
- result = RESULT_KLV_CODING;
- }
- }
-
- if ( ASDCP_SUCCESS(result) )
- result = m_File.Writev(Overhead.Data(), Overhead.Length());
- }
-
- if ( ASDCP_SUCCESS(result) )
- {
- m_StreamOffset += Overhead.Length();
- // write encrypted source value
- result = m_File.Writev((byte_t*)m_CtFrameBuf.RoData(), m_CtFrameBuf.Size());
- }
-
- if ( ASDCP_SUCCESS(result) )
- {
- m_StreamOffset += m_CtFrameBuf.Size();
-
- byte_t hmoverhead[512];
- Kumu::MemIOWriter HMACOverhead(hmoverhead, 512);
-
- // write the HMAC
- if ( m_Info.UsesHMAC )
- {
- HMACOverhead.WriteRaw(IntPack.Data, klv_intpack_size);
- }
- else
- { // we still need the var-pack length values if the intpack is empty
- for ( ui32_t i = 0; i < 3 ; i++ )
- HMACOverhead.WriteBER(0, MXF_BER_LENGTH);
- }
-
- // write HMAC
- result = m_File.Writev(HMACOverhead.Data(), HMACOverhead.Length());
- m_StreamOffset += HMACOverhead.Length();
- }
- }
- else
- {
- ui32_t BER_length = MXF_BER_LENGTH;
-
- if ( FrameBuf.Size() > 0x00ffffff ) // Need BER integer longer than MXF_BER_LENGTH bytes
- {
- BER_length = Kumu::get_BER_length_for_value(FrameBuf.Size());
-
- if ( BER_length == 0 )
- result = RESULT_KLV_CODING;
- }
-
- Overhead.WriteRaw((byte_t*)EssenceUL, SMPTE_UL_LENGTH);
- Overhead.WriteBER(FrameBuf.Size(), BER_length);
-
- if ( ASDCP_SUCCESS(result) )
- result = m_File.Writev(Overhead.Data(), Overhead.Length());
-
- if ( ASDCP_SUCCESS(result) )
- result = m_File.Writev((byte_t*)FrameBuf.RoData(), FrameBuf.Size());
-
- if ( ASDCP_SUCCESS(result) )
- m_StreamOffset += Overhead.Length() + FrameBuf.Size();
- }
-
- if ( ASDCP_SUCCESS(result) )
- result = m_File.Writev();
-
return result;
}
+
//
// end h__02_Writer.cpp
/*
-Copyright (c) 2004-2012, John Hurst
+Copyright (c) 2004-2013, John Hurst
All rights reserved.
Redistribution and use in source and binary forms, with or without
if ( ! sg_DefaultMDTypesInit )
{
sg_dict = &DefaultSMPTEDict();
- g_OPAtomHeader = new ASDCP::MXF::OPAtomHeader(sg_dict);
+ g_OP1aHeader = new ASDCP::MXF::OP1aHeader(sg_dict);
g_OPAtomIndexFooter = new ASDCP::MXF::OPAtomIndexFooter(sg_dict);
+ g_RIP = new ASDCP::MXF::RIP(sg_dict);
sg_DefaultMDTypesInit = true;
}
}
//
//
-ASDCP::h__ASDCPReader::h__ASDCPReader(const Dictionary& d) : MXF::TrackFileReader<OPAtomHeader, OPAtomIndexFooter>(d), m_BodyPart(m_Dict) {}
+ASDCP::h__ASDCPReader::h__ASDCPReader(const Dictionary& d) : MXF::TrackFileReader<OP1aHeader, OPAtomIndexFooter>(d), m_BodyPart(m_Dict) {}
ASDCP::h__ASDCPReader::~h__ASDCPReader() {}
Result_t
ASDCP::h__ASDCPReader::OpenMXFRead(const char* filename)
{
- Result_t result = ASDCP::MXF::TrackFileReader<OPAtomHeader, OPAtomIndexFooter>::OpenMXFRead(filename);
+ Result_t result = ASDCP::MXF::TrackFileReader<OP1aHeader, OPAtomIndexFooter>::OpenMXFRead(filename);
if ( KM_SUCCESS(result) )
- {
- // if this is a three partition file, go to the body
- // partition and read the partition pack
- if ( m_HeaderPart.m_RIP.PairArray.size() > 2 )
- {
- Array<RIP::Pair>::iterator r_i = m_HeaderPart.m_RIP.PairArray.begin();
- r_i++;
- m_File.Seek((*r_i).ByteOffset);
- result = m_BodyPart.InitFromFile(m_File);
- if( !ASDCP_SUCCESS(result) )
- {
- DefaultLogSink().Error("ASDCP::h__Reader::OpenMXFRead, m_BodyPart.InitFromFile failed\n");
- }
- }
- }
- else
- DefaultLogSink().Error("ASDCP::h__Reader::OpenMXFRead, TrackFileReader::OpenMXFRead failed\n");
-
-
- if ( KM_SUCCESS(result) )
- m_HeaderPart.BodyOffset = m_File.Tell();
-
- return result;
-}
-
-//
-Result_t
-ASDCP::h__ASDCPReader::InitInfo()
-{
- Result_t result = ASDCP::MXF::TrackFileReader<OPAtomHeader, OPAtomIndexFooter>::InitInfo();
+ result = ASDCP::MXF::TrackFileReader<OP1aHeader, OPAtomIndexFooter>::InitInfo();
if( KM_SUCCESS(result) )
{
+ //
InterchangeObject* Object;
m_Info.LabelSetType = LS_MXF_UNKNOWN;
if ( m_HeaderPart.OperationalPattern.ExactMatch(MXFInterop_OPAtom_Entry().ul) )
{
- m_Info.LabelSetType = LS_MXF_INTEROP;
+ m_Info.LabelSetType = LS_MXF_INTEROP;
}
else if ( m_HeaderPart.OperationalPattern.ExactMatch(SMPTE_390_OPAtom_Entry().ul) )
{
m_Info.LabelSetType = LS_MXF_SMPTE;
}
- }
-
- return result;
-}
+ else
+ {
+ char strbuf[IdentBufferLen];
+ const MDDEntry* Entry = m_Dict->FindUL(m_HeaderPart.OperationalPattern.Value());
-// AS-DCP method of populating the in-memory index
-Result_t
-ASDCP::h__ASDCPReader::InitMXFIndex()
-{
- if ( ! m_File.IsOpen() )
- return RESULT_INIT;
+ if ( Entry == 0 )
+ {
+ DefaultLogSink().Warn("Operational pattern is not OP-Atom: %s\n",
+ m_HeaderPart.OperationalPattern.EncodeString(strbuf, IdentBufferLen));
+ }
+ else
+ {
+ DefaultLogSink().Warn("Operational pattern is not OP-Atom: %s\n", Entry->name);
+ }
+ }
- Result_t result = m_File.Seek(m_HeaderPart.FooterPartition);
+ //
+ if ( m_RIP.PairArray.size() < 2 )
+ {
+ // OP-Atom states that there will be either two or three partitions:
+ // one closed header and one closed footer with an optional body
+ // SMPTE 429-5 files may have many partitions, see SMPTE ST 410.
+ DefaultLogSink().Warn("RIP entry count is less than 2: %u\n", m_RIP.PairArray.size());
+ }
+ else if ( m_RIP.PairArray.size() > 2 )
+ {
+ // if this is a three partition file, go to the body
+ // partition and read the partition pack
+ Array<RIP::Pair>::iterator r_i = m_RIP.PairArray.begin();
+ r_i++;
+ m_File.Seek((*r_i).ByteOffset);
+ result = m_BodyPart.InitFromFile(m_File);
+
+ if( ASDCP_FAILURE(result) )
+ {
+ DefaultLogSink().Error("ASDCP::h__ASDCPReader::OpenMXFRead, m_BodyPart.InitFromFile failed\n");
+ }
+ }
+ else if ( m_RIP.PairArray.front().ByteOffset != 0 )
+ {
+ DefaultLogSink().Error("First Partition in RIP is not at offset 0.\n");
+ result = RESULT_FORMAT;
+ }
+ }
- if ( ASDCP_SUCCESS(result) )
+ if ( KM_SUCCESS(result) )
{
- m_FooterPart.m_Lookup = &m_HeaderPart.m_Primer;
- result = m_FooterPart.InitFromFile(m_File);
- }
+ m_HeaderPart.BodyOffset = m_File.Tell();
+
+ result = m_File.Seek(m_HeaderPart.FooterPartition);
- if ( ASDCP_SUCCESS(result) )
- m_File.Seek(m_HeaderPart.BodyOffset);
+ if ( ASDCP_SUCCESS(result) )
+ {
+ m_IndexAccess.m_Lookup = &m_HeaderPart.m_Primer;
+ result = m_IndexAccess.InitFromFile(m_File);
+ }
+ }
+ m_File.Seek(m_HeaderPart.BodyOffset);
return result;
}
-
// AS-DCP method of reading a plaintext or encrypted frame
Result_t
ASDCP::h__ASDCPReader::ReadEKLVFrame(ui32_t FrameNum, ASDCP::FrameBuffer& FrameBuf,
const byte_t* EssenceUL, AESDecContext* Ctx, HMACContext* HMAC)
{
- return ASDCP::MXF::TrackFileReader<OPAtomHeader, OPAtomIndexFooter>::ReadEKLVFrame(m_HeaderPart, FrameNum, FrameBuf,
+ return ASDCP::MXF::TrackFileReader<OP1aHeader, OPAtomIndexFooter>::ReadEKLVFrame(m_HeaderPart, FrameNum, FrameBuf,
EssenceUL, Ctx, HMAC);
}
ASDCP::h__ASDCPReader::LocateFrame(ui32_t FrameNum, Kumu::fpos_t& streamOffset,
i8_t& temporalOffset, i8_t& keyFrameOffset)
{
- return ASDCP::MXF::TrackFileReader<OPAtomHeader, OPAtomIndexFooter>::LocateFrame(m_HeaderPart, FrameNum,
+ return ASDCP::MXF::TrackFileReader<OP1aHeader, OPAtomIndexFooter>::LocateFrame(m_HeaderPart, FrameNum,
streamOffset, temporalOffset, keyFrameOffset);
}
// base subroutine for reading a KLV packet, assumes file position is at the first byte of the packet
Result_t
-ASDCP::Read_EKLV_Packet(Kumu::FileReader& File, const ASDCP::Dictionary& Dict, const MXF::OPAtomHeader& HeaderPart,
+ASDCP::Read_EKLV_Packet(Kumu::FileReader& File, const ASDCP::Dictionary& Dict, const MXF::OP1aHeader& HeaderPart,
const ASDCP::WriterInfo& Info, Kumu::fpos_t& LastPosition, ASDCP::FrameBuffer& CtFrameBuf,
ui32_t FrameNum, ui32_t SequenceNum, ASDCP::FrameBuffer& FrameBuf,
const byte_t* EssenceUL, AESDecContext* Ctx, HMACContext* HMAC)
{
char strbuf[IntBufferLen];
const MDDEntry* Entry = Dict.FindUL(Key.Value());
+
if ( Entry == 0 )
- DefaultLogSink().Warn("Unexpected Essence UL found: %s.\n", Key.EncodeString(strbuf, IntBufferLen));
+ {
+ DefaultLogSink().Warn("Unexpected Essence UL found: %s.\n", Key.EncodeString(strbuf, IntBufferLen));
+ }
else
- DefaultLogSink().Warn("Unexpected Essence UL found: %s.\n", Entry->name);
+ {
+ DefaultLogSink().Warn("Unexpected Essence UL found: %s.\n", Entry->name);
+ }
+
return RESULT_FORMAT;
}
+
ess_p += SMPTE_UL_LENGTH;
// read SourceLength length
{
char strbuf[IntBufferLen];
const MDDEntry* Entry = Dict.FindUL(Key.Value());
+
if ( Entry == 0 )
- DefaultLogSink().Warn("Unexpected Essence UL found: %s.\n", Key.EncodeString(strbuf, IntBufferLen));
+ {
+ DefaultLogSink().Warn("Unexpected Essence UL found: %s.\n", Key.EncodeString(strbuf, IntBufferLen));
+ }
else
- DefaultLogSink().Warn("Unexpected Essence UL found: %s.\n", Entry->name);
+ {
+ DefaultLogSink().Warn("Unexpected Essence UL found: %s.\n", Entry->name);
+ }
return RESULT_FORMAT;
}
/*
-Copyright (c) 2004-2012, John Hurst
+Copyright (c) 2004-2013, John Hurst
All rights reserved.
Redistribution and use in source and binary forms, with or without
using namespace ASDCP;
using namespace ASDCP::MXF;
-// a magic number identifying asdcplib
-#ifndef ASDCP_BUILD_NUMBER
-#define ASDCP_BUILD_NUMBER 0x6A68
-#endif
-
-
-
-//
-ASDCP::h__Writer::h__Writer(const Dictionary& d) :
- m_HeaderPart(m_Dict), m_BodyPart(m_Dict), m_FooterPart(m_Dict), m_Dict(&d),
- m_HeaderSize(0), m_EssenceStart(0),
- m_EssenceDescriptor(0), m_FramesWritten(0), m_StreamOffset(0)
-{
- default_md_object_init();
-}
-
-ASDCP::h__Writer::~h__Writer()
-{
-}
-
//
// add DMS CryptographicFramework entry to source package
void
Context->CryptographicKeyID.Set(Descr.CryptographicKeyID);
}
-//
-void
-ASDCP::h__Writer::InitHeader()
-{
- assert(m_Dict);
- assert(m_EssenceDescriptor);
-
- m_HeaderPart.m_Primer.ClearTagList();
- m_HeaderPart.m_Preface = new Preface(m_Dict);
- m_HeaderPart.AddChildObject(m_HeaderPart.m_Preface);
-
- // Set the Operational Pattern label -- we're just starting and have no RIP or index,
- // so we tell the world by using OP1a
- m_HeaderPart.m_Preface->OperationalPattern = UL(m_Dict->ul(MDD_OP1a));
- m_HeaderPart.OperationalPattern = m_HeaderPart.m_Preface->OperationalPattern;
-
- // First RIP Entry
- if ( m_Info.LabelSetType == LS_MXF_SMPTE )
- m_HeaderPart.m_RIP.PairArray.push_back(RIP::Pair(0, 0)); // 3-part, no essence in header
- else
- m_HeaderPart.m_RIP.PairArray.push_back(RIP::Pair(1, 0)); // 2-part, essence in header
-
- //
- // Identification
- //
- Identification* Ident = new Identification(m_Dict);
- m_HeaderPart.AddChildObject(Ident);
- m_HeaderPart.m_Preface->Identifications.push_back(Ident->InstanceUID);
-
- Kumu::GenRandomValue(Ident->ThisGenerationUID);
- Ident->CompanyName = m_Info.CompanyName.c_str();
- Ident->ProductName = m_Info.ProductName.c_str();
- Ident->VersionString = m_Info.ProductVersion.c_str();
- Ident->ProductUID.Set(m_Info.ProductUUID);
- Ident->Platform = ASDCP_PLATFORM;
-
- std::vector<int> version = version_split(Version());
-
- Ident->ToolkitVersion.Major = version[0];
- Ident->ToolkitVersion.Minor = version[1];
- Ident->ToolkitVersion.Patch = version[2];
- 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, const Dictionary*& Dict)
-{
- TrackSet<ClipT> NewTrack;
-
- NewTrack.Track = new Track(Dict);
- 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(Dict);
- 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, const Dictionary*& Dict)
-{
- assert(Dict);
- UL TCUL(Dict->ul(MDD_TimecodeDataDef));
-
- TrackSet<TimecodeComponent> NewTrack = CreateTrackAndSequence<PackageT, TimecodeComponent>(Header, Package, "Timecode Track", EditRate, TCUL, 1, Dict);
-
- NewTrack.Clip = new TimecodeComponent(Dict);
- 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& EssenceUL,
- const UL& DataDefinition, const std::string& PackageLabel)
-{
- //
- ContentStorage* Storage = new ContentStorage(m_Dict);
- m_HeaderPart.AddChildObject(Storage);
- m_HeaderPart.m_Preface->ContentStorage = Storage->InstanceUID;
-
- EssenceContainerData* ECD = new EssenceContainerData(m_Dict);
- m_HeaderPart.AddChildObject(ECD);
- Storage->EssenceContainerData.push_back(ECD->InstanceUID);
- 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
- //
- m_MaterialPackage = new MaterialPackage(m_Dict);
- 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_Dict);
- m_DurationUpdateList.push_back(&(MPTCTrack.Sequence->Duration));
- m_DurationUpdateList.push_back(&(MPTCTrack.Clip->Duration));
-
- TrackSet<SourceClip> MPTrack =
- CreateTrackAndSequence<MaterialPackage, SourceClip>(m_HeaderPart, *m_MaterialPackage,
- TrackName, EditRate, DataDefinition,
- 2, m_Dict);
- m_DurationUpdateList.push_back(&(MPTrack.Sequence->Duration));
-
- MPTrack.Clip = new SourceClip(m_Dict);
- 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_Dict);
- 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_Dict);
- 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_Dict);
- m_DurationUpdateList.push_back(&(FPTrack.Sequence->Duration));
-
- // Consult ST 379:2004 Sec. 6.3, "Element to track relationship" to see where "12" comes from.
- FPTrack.Track->TrackNumber = KM_i32_BE(Kumu::cp2i<ui32_t>((EssenceUL.Value() + 12)));
-
- FPTrack.Clip = new SourceClip(m_Dict);
- 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_Dict);
- m_HeaderPart.AddChildObject(Storage);
- m_HeaderPart.m_Preface->ContentStorage = Storage->InstanceUID;
-
- EssenceContainerData* ECD = new EssenceContainerData(m_Dict);
- m_HeaderPart.AddChildObject(ECD);
- Storage->EssenceContainerData.push_back(ECD->InstanceUID);
- 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
- //
- m_MaterialPackage = new MaterialPackage(m_Dict);
- 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_Dict);
- 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_Dict);
- m_DurationUpdateList.push_back(&(MPTrack.Sequence->Duration));
-
- MPTrack.Clip = new DMSegment(m_Dict);
- 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));
+ASDCP::h__ASDCPWriter::h__ASDCPWriter(const Dictionary& d) :
+ MXF::TrackFileWriter<OP1aHeader>(d), m_BodyPart(m_Dict), m_FooterPart(m_Dict) {}
-
- //
- // File (Source) Package
- //
- m_FilePackage = new SourcePackage(m_Dict);
- 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_Dict);
- m_DurationUpdateList.push_back(&(FPTCTrack.Sequence->Duration));
- m_DurationUpdateList.push_back(&(FPTCTrack.Clip->Duration));
-
- TrackSet<DMSegment> FPTrack =
- CreateTrackAndSequence<SourcePackage, DMSegment>(m_HeaderPart, *m_FilePackage,
- TrackName, EditRate, DataDefinition,
- 2, m_Dict);
- m_DurationUpdateList.push_back(&(FPTrack.Sequence->Duration));
-
- FPTrack.Clip = new DMSegment(m_Dict);
- 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;
-}
+ASDCP::h__ASDCPWriter::~h__ASDCPWriter() {}
-//
-void
-ASDCP::h__Writer::AddEssenceDescriptor(const UL& WrappingUL)
-{
- //
- // Essence Descriptor
- //
- m_EssenceDescriptor->EssenceContainer = WrappingUL;
- m_HeaderPart.m_Preface->PrimaryPackage = m_FilePackage->InstanceUID;
-
- //
- // Essence Descriptors
- //
- assert(m_Dict);
- UL GenericContainerUL(m_Dict->ul(MDD_GCMulti));
- m_HeaderPart.EssenceContainers.push_back(GenericContainerUL);
-
- if ( m_Info.EncryptedEssence )
- {
- UL CryptEssenceUL(m_Dict->ul(MDD_EncryptedContainerLabel));
- m_HeaderPart.EssenceContainers.push_back(CryptEssenceUL);
- m_HeaderPart.m_Preface->DMSchemes.push_back(UL(m_Dict->ul(MDD_CryptographicFrameworkLabel)));
- AddDMScrypt(m_HeaderPart, *m_FilePackage, m_Info, WrappingUL, m_Dict);
- }
- else
- {
- m_HeaderPart.EssenceContainers.push_back(WrappingUL);
- }
-
- m_HeaderPart.m_Preface->EssenceContainers = m_HeaderPart.EssenceContainers;
- m_HeaderPart.AddChildObject(m_EssenceDescriptor);
-
- std::list<InterchangeObject*>::iterator sdli = m_EssenceSubDescriptorList.begin();
- for ( ; sdli != m_EssenceSubDescriptorList.end(); sdli++ )
- m_HeaderPart.AddChildObject(*sdli);
-
- m_FilePackage->Descriptor = m_EssenceDescriptor->InstanceUID;
-}
//
Result_t
-ASDCP::h__Writer::CreateBodyPart(const MXF::Rational& EditRate, ui32_t BytesPerEditUnit)
+ASDCP::h__ASDCPWriter::CreateBodyPart(const MXF::Rational& EditRate, ui32_t BytesPerEditUnit)
{
assert(m_Dict);
Result_t result = RESULT_OK;
m_BodyPart.BodySID = 1;
UL OPAtomUL(m_Dict->ul(MDD_OPAtom));
m_BodyPart.OperationalPattern = OPAtomUL;
- m_HeaderPart.m_RIP.PairArray.push_back(RIP::Pair(1, m_BodyPart.ThisPartition)); // Second RIP Entry
+ m_RIP.PairArray.push_back(RIP::Pair(1, m_BodyPart.ThisPartition)); // Second RIP Entry
UL BodyUL(m_Dict->ul(MDD_ClosedCompleteBodyPartition));
result = m_BodyPart.WriteToFile(m_File, BodyUL);
m_FooterPart.IndexSID = 129;
if ( BytesPerEditUnit == 0 )
- m_FooterPart.SetIndexParamsVBR(&m_HeaderPart.m_Primer, EditRate, ECoffset);
+ {
+ m_FooterPart.SetIndexParamsVBR(&m_HeaderPart.m_Primer, EditRate, ECoffset);
+ }
else
- m_FooterPart.SetIndexParamsCBR(&m_HeaderPart.m_Primer, BytesPerEditUnit, EditRate);
+ {
+ m_FooterPart.SetIndexParamsCBR(&m_HeaderPart.m_Primer, BytesPerEditUnit, EditRate);
+ }
}
return result;
//
Result_t
-ASDCP::h__Writer::WriteMXFHeader(const std::string& PackageLabel, const UL& WrappingUL,
- const std::string& TrackName, const UL& EssenceUL, const UL& DataDefinition,
- const MXF::Rational& EditRate, ui32_t TCFrameRate, ui32_t BytesPerEditUnit)
+ASDCP::h__ASDCPWriter::WriteASDCPHeader(const std::string& PackageLabel, const UL& WrappingUL,
+ const std::string& TrackName, const UL& EssenceUL, const UL& DataDefinition,
+ const MXF::Rational& EditRate, ui32_t TCFrameRate, ui32_t BytesPerEditUnit)
{
InitHeader();
+
+ // First RIP Entry
+ if ( m_Info.LabelSetType == LS_MXF_SMPTE ) // ERK
+ {
+ m_RIP.PairArray.push_back(RIP::Pair(0, 0)); // 3-part, no essence in header
+ }
+ else
+ {
+ m_RIP.PairArray.push_back(RIP::Pair(1, 0)); // 2-part, essence in header
+ }
+
AddSourceClip(EditRate, TCFrameRate, TrackName, EssenceUL, DataDefinition, PackageLabel);
AddEssenceDescriptor(WrappingUL);
}
+
+// standard method of writing the header and footer of a completed MXF file
+//
+Result_t
+ASDCP::h__ASDCPWriter::WriteASDCPFooter()
+{
+ // update all Duration properties
+ 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_RIP.PairArray.back().ByteOffset;
+
+ Kumu::fpos_t here = m_File.Tell();
+ m_RIP.PairArray.push_back(RIP::Pair(0, here)); // Last RIP Entry
+ m_HeaderPart.FooterPartition = here;
+
+ assert(m_Dict);
+ // re-label the header partition, set the footer
+ UL OPAtomUL(m_Dict->ul(MDD_OPAtom));
+ m_HeaderPart.OperationalPattern = OPAtomUL;
+ m_HeaderPart.m_Preface->OperationalPattern = OPAtomUL;
+ m_FooterPart.OperationalPattern = OPAtomUL;
+
+ m_FooterPart.EssenceContainers = m_HeaderPart.EssenceContainers;
+ m_FooterPart.FooterPartition = here;
+ m_FooterPart.ThisPartition = here;
+
+ Result_t result = m_FooterPart.WriteToFile(m_File, m_FramesWritten);
+
+ if ( ASDCP_SUCCESS(result) )
+ result = m_RIP.WriteToFile(m_File);
+
+ if ( ASDCP_SUCCESS(result) )
+ result = m_File.Seek(0);
+
+ if ( ASDCP_SUCCESS(result) )
+ result = m_HeaderPart.WriteToFile(m_File, m_HeaderSize);
+
+ m_File.Close();
+ return result;
+}
+
+
+//------------------------------------------------------------------------------------------
+//
+
+
// standard method of writing a plaintext or encrypted frame
Result_t
-ASDCP::h__Writer::WriteEKLVPacket(const ASDCP::FrameBuffer& FrameBuf, const byte_t* EssenceUL,
- AESEncContext* Ctx, HMACContext* HMAC)
+ASDCP::Write_EKLV_Packet(Kumu::FileWriter& File, const ASDCP::Dictionary& Dict, const MXF::OP1aHeader& HeaderPart,
+ const ASDCP::WriterInfo& Info, ASDCP::FrameBuffer& CtFrameBuf, ui32_t& FramesWritten,
+ ui64_t & StreamOffset, const ASDCP::FrameBuffer& FrameBuf, const byte_t* EssenceUL,
+ AESEncContext* Ctx, HMACContext* HMAC)
{
Result_t result = RESULT_OK;
IntegrityPack IntPack;
byte_t overhead[128];
Kumu::MemIOWriter Overhead(overhead, 128);
- assert(m_Dict);
if ( FrameBuf.Size() == 0 )
{
return RESULT_EMPTY_FB;
}
- if ( m_Info.EncryptedEssence )
+ if ( Info.EncryptedEssence )
{
if ( ! Ctx )
return RESULT_CRYPT_CTX;
- if ( m_Info.UsesHMAC && ! HMAC )
+ if ( Info.UsesHMAC && ! HMAC )
return RESULT_HMAC_CTX;
if ( FrameBuf.PlaintextOffset() > FrameBuf.Size() )
return RESULT_LARGE_PTO;
// encrypt the essence data (create encrypted source value)
- result = EncryptFrameBuffer(FrameBuf, m_CtFrameBuf, Ctx);
+ result = EncryptFrameBuffer(FrameBuf, CtFrameBuf, Ctx);
// create HMAC
- if ( ASDCP_SUCCESS(result) && m_Info.UsesHMAC )
- result = IntPack.CalcValues(m_CtFrameBuf, m_Info.AssetUUID, m_FramesWritten + 1, HMAC);
+ if ( ASDCP_SUCCESS(result) && Info.UsesHMAC )
+ result = IntPack.CalcValues(CtFrameBuf, Info.AssetUUID, FramesWritten + 1, HMAC);
if ( ASDCP_SUCCESS(result) )
{ // write UL
- Overhead.WriteRaw(m_Dict->ul(MDD_CryptEssence), SMPTE_UL_LENGTH);
+ Overhead.WriteRaw(Dict.ul(MDD_CryptEssence), SMPTE_UL_LENGTH);
// construct encrypted triplet header
- ui32_t ETLength = klv_cryptinfo_size + m_CtFrameBuf.Size();
+ ui32_t ETLength = klv_cryptinfo_size + CtFrameBuf.Size();
ui32_t BER_length = MXF_BER_LENGTH;
- if ( m_Info.UsesHMAC )
+ if ( Info.UsesHMAC )
ETLength += klv_intpack_size;
else
ETLength += (MXF_BER_LENGTH * 3); // for empty intpack
{
if ( ! ( Overhead.WriteBER(ETLength, BER_length) // write encrypted triplet length
&& Overhead.WriteBER(UUIDlen, MXF_BER_LENGTH) // write ContextID length
- && Overhead.WriteRaw(m_Info.ContextID, UUIDlen) // write ContextID
+ && Overhead.WriteRaw(Info.ContextID, UUIDlen) // write ContextID
&& Overhead.WriteBER(sizeof(ui64_t), MXF_BER_LENGTH) // write PlaintextOffset length
&& Overhead.WriteUi64BE(FrameBuf.PlaintextOffset()) // write PlaintextOffset
&& Overhead.WriteBER(SMPTE_UL_LENGTH, MXF_BER_LENGTH) // write essence UL length
&& Overhead.WriteRaw((byte_t*)EssenceUL, SMPTE_UL_LENGTH) // write the essence UL
&& Overhead.WriteBER(sizeof(ui64_t), MXF_BER_LENGTH) // write SourceLength length
&& Overhead.WriteUi64BE(FrameBuf.Size()) // write SourceLength
- && Overhead.WriteBER(m_CtFrameBuf.Size(), BER_length) ) ) // write ESV length
+ && Overhead.WriteBER(CtFrameBuf.Size(), BER_length) ) ) // write ESV length
{
result = RESULT_KLV_CODING;
}
}
if ( ASDCP_SUCCESS(result) )
- result = m_File.Writev(Overhead.Data(), Overhead.Length());
+ result = File.Writev(Overhead.Data(), Overhead.Length());
}
if ( ASDCP_SUCCESS(result) )
{
- m_StreamOffset += Overhead.Length();
+ StreamOffset += Overhead.Length();
// write encrypted source value
- result = m_File.Writev((byte_t*)m_CtFrameBuf.RoData(), m_CtFrameBuf.Size());
+ result = File.Writev((byte_t*)CtFrameBuf.RoData(), CtFrameBuf.Size());
}
if ( ASDCP_SUCCESS(result) )
{
- m_StreamOffset += m_CtFrameBuf.Size();
+ StreamOffset += CtFrameBuf.Size();
byte_t hmoverhead[512];
Kumu::MemIOWriter HMACOverhead(hmoverhead, 512);
// write the HMAC
- if ( m_Info.UsesHMAC )
+ if ( Info.UsesHMAC )
{
HMACOverhead.WriteRaw(IntPack.Data, klv_intpack_size);
}
}
// write HMAC
- result = m_File.Writev(HMACOverhead.Data(), HMACOverhead.Length());
- m_StreamOffset += HMACOverhead.Length();
+ result = File.Writev(HMACOverhead.Data(), HMACOverhead.Length());
+ StreamOffset += HMACOverhead.Length();
}
}
else
Overhead.WriteBER(FrameBuf.Size(), BER_length);
if ( ASDCP_SUCCESS(result) )
- result = m_File.Writev(Overhead.Data(), Overhead.Length());
+ result = File.Writev(Overhead.Data(), Overhead.Length());
if ( ASDCP_SUCCESS(result) )
- result = m_File.Writev((byte_t*)FrameBuf.RoData(), FrameBuf.Size());
+ result = File.Writev((byte_t*)FrameBuf.RoData(), FrameBuf.Size());
if ( ASDCP_SUCCESS(result) )
- m_StreamOffset += Overhead.Length() + FrameBuf.Size();
+ StreamOffset += Overhead.Length() + FrameBuf.Size();
}
if ( ASDCP_SUCCESS(result) )
- result = m_File.Writev();
-
- return result;
-}
-
-
-// standard method of writing the header and footer of a completed MXF file
-//
-Result_t
-ASDCP::h__Writer::WriteMXFFooter()
-{
- // 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 =
-
- 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.FooterPartition = here;
+ result = File.Writev();
- assert(m_Dict);
- // re-label the partition
- UL OPAtomUL(m_Dict->ul(MDD_OPAtom));
- m_HeaderPart.OperationalPattern = OPAtomUL;
- m_HeaderPart.m_Preface->OperationalPattern = m_HeaderPart.OperationalPattern;
-
- m_FooterPart.OperationalPattern = m_HeaderPart.OperationalPattern;
- m_FooterPart.EssenceContainers = m_HeaderPart.EssenceContainers;
- m_FooterPart.FooterPartition = here;
- m_FooterPart.ThisPartition = here;
-
- Result_t result = m_FooterPart.WriteToFile(m_File, m_FramesWritten);
-
- if ( ASDCP_SUCCESS(result) )
- result = m_HeaderPart.m_RIP.WriteToFile(m_File);
-
- if ( ASDCP_SUCCESS(result) )
- result = m_File.Seek(0);
-
- if ( ASDCP_SUCCESS(result) )
- result = m_HeaderPart.WriteToFile(m_File, m_HeaderSize);
-
- m_File.Close();
return result;
}
{
Kumu::FileReader Reader;
const Dictionary* Dict = &DefaultCompositeDict();
- ASDCP::MXF::OPAtomHeader Header(Dict);
+ ASDCP::MXF::OP1aHeader Header(Dict);
+ ASDCP::MXF::RIP RIP(Dict);
result = Reader.OpenRead((*fi).c_str());
+ if ( ASDCP_SUCCESS(result) )
+ result = MXF::SeekToRIP(Reader);
+
+ if ( ASDCP_SUCCESS(result) )
+ {
+ result = RIP.InitFromFile(Reader);
+ ui32_t test_s = RIP.PairArray.size();
+
+ if ( ASDCP_FAILURE(result) )
+ {
+ DefaultLogSink().Error("File contains no RIP\n");
+ result = RESULT_OK;
+ }
+ else if ( RIP.PairArray.empty() )
+ {
+ DefaultLogSink().Error("RIP contains no Pairs.\n");
+ }
+
+ Reader.Seek(0);
+ }
+ else
+ {
+ DefaultLogSink().Error("ASDCP::h__Reader::OpenMXFRead, SeekToRIP failed\n");
+ }
+
if ( ASDCP_SUCCESS(result) )
result = Header.InitFromFile(Reader);
if ( ASDCP_SUCCESS(result) )
Header.Dump(stdout);
- if ( ASDCP_SUCCESS(result) && Header.m_RIP.PairArray.size() > 2 )
+ if ( ASDCP_SUCCESS(result) && RIP.PairArray.size() > 2 )
{
- MXF::Array<MXF::RIP::Pair>::const_iterator pi = Header.m_RIP.PairArray.begin();
+ MXF::Array<MXF::RIP::Pair>::const_iterator pi = RIP.PairArray.begin();
- for ( pi++; pi != Header.m_RIP.PairArray.end() && ASDCP_SUCCESS(result); pi++ )
+ for ( pi++; pi != RIP.PairArray.end() && ASDCP_SUCCESS(result); pi++ )
{
result = Reader.Seek((*pi).ByteOffset);
}
if ( ASDCP_SUCCESS(result) )
- Header.m_RIP.Dump(stdout);
+ RIP.Dump(stdout);
}
else // dump klv
{