public:
PictureDescriptor m_PDesc;
+ byte_t m_EssenceUL[SMPTE_UL_LENGTH];
ASDCP_NO_COPY_CONSTRUCT(h__Writer);
- h__Writer() : m_EssenceSubDescriptor(0) {}
+ h__Writer() : m_EssenceSubDescriptor(0) {
+ memset(m_EssenceUL, 0, SMPTE_UL_LENGTH);
+ }
+
~h__Writer(){}
Result_t OpenWrite(const char*, ui32_t HeaderSize);
m_PDesc.EditRate, 24 /* TCFrameRate */);
if ( ASDCP_SUCCESS(result) )
- result = m_State.Goto_READY();
+ {
+ memcpy(m_EssenceUL, Dict::ul(MDD_JPEG2000Essence), SMPTE_UL_LENGTH);
+ m_EssenceUL[SMPTE_UL_LENGTH-1] = 1; // first (and only) essence container
+ result = m_State.Goto_READY();
+ }
return result;
}
Entry.StreamOffset = m_StreamOffset;
if ( ASDCP_SUCCESS(result) )
- result = WriteEKLVPacket(FrameBuf, Dict::ul(MDD_JPEG2000Essence), Ctx, HMAC);
+ result = WriteEKLVPacket(FrameBuf, m_EssenceUL, Ctx, HMAC);
if ( ASDCP_SUCCESS(result) )
{
public:
VideoDescriptor m_VDesc;
ui32_t m_GOPOffset;
+ byte_t m_EssenceUL[SMPTE_UL_LENGTH];
ASDCP_NO_COPY_CONSTRUCT(h__Writer);
- h__Writer() : m_GOPOffset(0) {}
+ h__Writer() : m_GOPOffset(0) {
+ memset(m_EssenceUL, 0, SMPTE_UL_LENGTH);
+ }
+
~h__Writer(){}
Result_t OpenWrite(const char*, ui32_t HeaderSize);
m_VDesc.EditRate, 24 /* TCFrameRate */);
if ( ASDCP_SUCCESS(result) )
- result = m_State.Goto_READY();
+ {
+ memcpy(m_EssenceUL, Dict::ul(MDD_MPEG2Essence), SMPTE_UL_LENGTH);
+ m_EssenceUL[SMPTE_UL_LENGTH-1] = 1; // first (and only) essence container
+ result = m_State.Goto_READY();
+ }
return result;
}
Entry.StreamOffset = m_StreamOffset;
if ( ASDCP_SUCCESS(result) )
- result = WriteEKLVPacket(FrameBuf, Dict::ul(MDD_MPEG2Essence), Ctx, HMAC);
+ result = WriteEKLVPacket(FrameBuf, m_EssenceUL, Ctx, HMAC);
if ( ASDCP_FAILURE(result) )
return result;
{
public:
AudioDescriptor m_ADesc;
+ byte_t m_EssenceUL[SMPTE_UL_LENGTH];
+
ASDCP_NO_COPY_CONSTRUCT(h__Writer);
- h__Writer(){}
+ h__Writer(){
+ memset(m_EssenceUL, 0, SMPTE_UL_LENGTH);
+ }
+
~h__Writer(){}
Result_t OpenWrite(const char*, ui32_t HeaderSize);
m_ADesc.SampleRate, 24 /* TCFrameRate */, calc_CBR_frame_size(m_Info, m_ADesc));
if ( ASDCP_SUCCESS(result) )
- result = m_State.Goto_READY();
+ {
+ memcpy(m_EssenceUL, Dict::ul(MDD_WAVEssence), SMPTE_UL_LENGTH);
+ m_EssenceUL[SMPTE_UL_LENGTH-1] = 1; // first (and only) essence container
+ result = m_State.Goto_READY();
+ }
return result;
}
result = m_State.Goto_RUNNING(); // first time through
if ( ASDCP_SUCCESS(result) )
- result = WriteEKLVPacket(FrameBuf, Dict::ul(MDD_WAVEssence), Ctx, HMAC);
+ result = WriteEKLVPacket(FrameBuf, m_EssenceUL, Ctx, HMAC);
if ( ASDCP_SUCCESS(result) )
m_FramesWritten++;
*/
+#include "Mutex.h"
#include "KLV.h"
#include "MDD.cpp"
#include <map>
+static ASDCP::Mutex s_Lock;
static bool s_md_init = false;
static std::map<ASDCP::UL, ui32_t> s_md_lookup;
{
if ( ! s_md_init )
{
- for ( ui32_t x = 0; x < s_MDD_Table_size; x++ )
- s_md_lookup.insert(std::map<UL, ui32_t>::value_type(UL(s_MDD_Table[x].ul), x));
+ AutoMutex AL(s_Lock);
+ if ( ! s_md_init )
+ {
+ for ( ui32_t x = 0; x < s_MDD_Table_size; x++ )
+ s_md_lookup.insert(std::map<UL, ui32_t>::value_type(UL(s_MDD_Table[x].ul), x));
+
+ s_md_init = true;
+ }
}
std::map<UL, ui32_t>::iterator i = s_md_lookup.find(UL(ul_buf));
if ( i == s_md_lookup.end() )
- return 0;
+ {
+ byte_t tmp_ul[SMPTE_UL_LENGTH];
+ memcpy(tmp_ul, ul_buf, SMPTE_UL_LENGTH);
+ tmp_ul[SMPTE_UL_LENGTH-1] = 0;
+
+ i = s_md_lookup.find(UL(tmp_ul));
+
+ if ( i == s_md_lookup.end() )
+ return 0;
+ }
return &s_MDD_Table[(*i).second];
}
0x0d, 0x01, 0x03, 0x01, 0x02, 0x06, 0x01, 0x00 },
{0}, false, "WAVWrapping" },
{ { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x02, // 10
- 0x0d, 0x01, 0x03, 0x01, 0x02, 0x04, 0x60, 0x01 },
+ 0x0d, 0x01, 0x03, 0x01, 0x02, 0x04, 0x60, 0x00 },
{0}, false, "MPEG2_VESWrapping" },
{ { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x07, // 11
0x0d, 0x01, 0x03, 0x01, 0x02, 0x0c, 0x01, 0x00 },
{0}, false, "JPEG_2000Wrapping" },
{ { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x02, 0x01, 0x01, // 12
- 0x0d, 0x01, 0x03, 0x01, 0x15, 0x01, 0x08, 0x01 },
+ 0x0d, 0x01, 0x03, 0x01, 0x15, 0x01, 0x08, 0x00 },
{0}, false, "JPEG2000Essence" },
{ { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x02, 0x01, 0x01, // 13
0x0d, 0x01, 0x03, 0x01, 0x15, 0x01, 0x05, 0x00 },
MajorVersion(1), MinorVersion(2),
KAGSize(1), ThisPartition(0), PreviousPartition(0),
FooterPartition(0), HeaderByteCount(0), IndexByteCount(0), IndexSID(0),
- BodyOffset(0), BodySID(1)
+ BodyOffset(0), BodySID(0)
{
m_PacketList = new h__PacketList;
}
if ( ASDCP_SUCCESS(result) )
result = Partition::InitFromFile(Reader); // test UL and OP
+ Partition::Dump();
+
// is it really OP-Atom?
UL OPAtomUL(Dict::ul(MDD_OPAtom));
UL InteropOPAtomUL(Dict::ul(MDD_MXFInterop_OPAtom));
return result;
}
- inline bool HasValue() const { return ! empty(); }
+ inline bool HasValue() const { return ! this->empty(); }
//
Result_t Archive(ASDCP::MemIOWriter& Writer) const {
if ( ASDCP_SUCCESS(result) )
result = Writer.WriteUi32BE(0);
- if ( ASDCP_FAILURE(result) || empty() )
+ if ( ASDCP_FAILURE(result) || this->empty() )
return result;
- typename std::vector<T>::const_iterator l_i = begin();
- assert(l_i != end());
+ typename std::vector<T>::const_iterator l_i = this->begin();
+ assert(l_i != this->end());
ui32_t ItemSize = Writer.Remainder();
result = (*l_i).Archive(Writer);
i2p<ui32_t>(ASDCP_i32_BE(ItemSize), p);
l_i++;
- for ( ; l_i != end() && ASDCP_SUCCESS(result); l_i++ )
+ for ( ; l_i != this->end() && ASDCP_SUCCESS(result); l_i++ )
result = (*l_i).Archive(Writer);
return result;
return RESULT_OK;
}
- inline bool HasValue() const { return ! empty(); }
+ inline bool HasValue() const { return ! this->empty(); }
//
Result_t Archive(ASDCP::MemIOWriter& Writer) const {
Result_t result = RESULT_OK;
- typename std::list<T>::const_iterator l_i = begin();
+ typename std::list<T>::const_iterator l_i = this->begin();
- for ( ; l_i != end() && ASDCP_SUCCESS(result); l_i++ )
+ for ( ; l_i != this->end() && ASDCP_SUCCESS(result); l_i++ )
result = (*l_i).Archive(Writer);
return result;
// partition and read off the partition pack
if ( m_HeaderPart.m_RIP.PairArray.size() == 3 )
{
- DefaultLogSink().Error("RIP count is 3: must write code...\n");
- return RESULT_FORMAT;
+ fprintf(stderr, "Three part!\n");
+ 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);
+ m_BodyPart.Dump();
+ // TODO: check the partition pack to make sure it is
+ // really a body with a single essence container
}
- // TODO: check the partition pack to make sure it is
- // really a body with a single essence container
m_EssenceStart = m_File.Tell();
-
return RESULT_OK;
}
return result;
UL Key(Reader.Key());
- UL CryptEssenceUL(Dict::ul(MDD_CryptEssence));
- UL InteropCryptEssenceUL(Dict::ul(MDD_MXFInterop_CryptEssence));
ui64_t PacketLength = Reader.Length();
m_LastPosition = m_LastPosition + Reader.KLLength() + PacketLength;
- if ( Key == InteropCryptEssenceUL || Key == CryptEssenceUL )
+ if ( memcmp(Key.Value(), Dict::ul(MDD_CryptEssence), Key.Size() - 1) == 0 // ignore the stream numbers
+ || memcmp(Key.Value(), Dict::ul(MDD_MXFInterop_CryptEssence), Key.Size() - 1) == 0 )
{
if ( ! m_Info.EncryptedEssence )
{
if ( ! read_test_BER(&ess_p, SMPTE_UL_LENGTH) )
return RESULT_FORMAT;
- // TODO: test essence UL
+ // test essence UL
+ if ( memcmp(ess_p, EssenceUL, SMPTE_UL_LENGTH - 1) != 0 ) // ignore the stream number
+ {
+ char strbuf[IntBufferLen];
+ const MDDEntry* Entry = Dict::FindUL(Key.Value());
+ if ( Entry == 0 )
+ DefaultLogSink().Warn("Unexpected Essence UL found: %s.\n", Key.ToString(strbuf));
+ else
+ DefaultLogSink().Warn("Unexpected Essence UL found: %s.\n", Entry->name);
+ return RESULT_FORMAT;
+ }
ess_p += SMPTE_UL_LENGTH;
// read SourceLength length
FrameBuf.PlaintextOffset(PlaintextOffset);
}
}
- else if ( Key == EssenceUL )
+ else if ( memcmp(Key.Value(), EssenceUL, Key.Size() - 1) == 0 ) // ignore the stream number
{ // read plaintext frame
if ( FrameBuf.Capacity() < PacketLength )
{
// a magic number identifying asdcplib
#ifndef ASDCP_BUILD_NUMBER
-#define ASDCP_BUILD_NUMBER 0x4A48
+#define ASDCP_BUILD_NUMBER 0x6A68
#endif
// so we tell the world by using OP1a
m_HeaderPart.m_Preface->OperationalPattern = UL(Dict::ul(MDD_OP1a));
m_HeaderPart.OperationalPattern = m_HeaderPart.m_Preface->OperationalPattern;
- m_HeaderPart.m_RIP.PairArray.push_back(RIP::Pair(1, 0)); // First RIP Entry
+ m_HeaderPart.m_RIP.PairArray.push_back(RIP::Pair(0, 0)); // First RIP Entry
//
// Identification
Ident->ProductName = m_Info.ProductName.c_str();
Ident->VersionString = m_Info.ProductVersion.c_str();
Ident->ProductUID.Set(m_Info.ProductUUID);
- // Ident->Platform = "Foonix"; // ASDCP_PLATFORM;
+ Ident->Platform = ASDCP_PLATFORM;
Ident->ToolkitVersion.Major = VERSION_MAJOR;
Ident->ToolkitVersion.Minor = VERSION_APIMINOR;
Ident->ToolkitVersion.Patch = VERSION_IMPMINOR;
//
UMID PackageUMID;
PackageUMID.MakeUMID(0x0f); // unidentified essence
-
m_MaterialPackage = new MaterialPackage;
m_MaterialPackage->Name = "AS-DCP Material Package";
m_MaterialPackage->PackageUID = PackageUMID;
-
m_HeaderPart.AddChildObject(m_MaterialPackage);
Storage->Packages.push_back(m_MaterialPackage->InstanceUID);
{
UL CryptEssenceUL(Dict::ul(MDD_EncryptedContainerLabel));
m_HeaderPart.EssenceContainers.push_back(CryptEssenceUL);
- m_HeaderPart.m_Preface->EssenceContainers.push_back(CryptEssenceUL);
m_HeaderPart.m_Preface->DMSchemes.push_back(UL(Dict::ul(MDD_CryptographicFrameworkLabel)));
AddDMScrypt(m_HeaderPart, *m_FilePackage, m_Info, WrappingUL);
}
{
m_HeaderPart.EssenceContainers.push_back(UL(Dict::ul(MDD_GCMulti)));
m_HeaderPart.EssenceContainers.push_back(WrappingUL);
- m_HeaderPart.m_Preface->EssenceContainers = m_HeaderPart.EssenceContainers;
}
+ m_HeaderPart.m_Preface->EssenceContainers = m_HeaderPart.EssenceContainers;
m_HeaderPart.AddChildObject(m_EssenceDescriptor);
m_FilePackage->Descriptor = m_EssenceDescriptor->InstanceUID;
// Write the header partition
Result_t result = m_HeaderPart.WriteToFile(m_File, m_HeaderSize);
- //
- // Body Partition
- //
-
+ if ( ASDCP_SUCCESS(result) )
+ {
+ // Body Partition
+ m_BodyPart.EssenceContainers = m_HeaderPart.EssenceContainers;
+ m_BodyPart.ThisPartition = m_File.Tell();
+ m_BodyPart.BodySID = 1;
+ UL OPAtomUL(Dict::ul(MDD_OPAtom));
+
+ if ( m_Info.LabelSetType == LS_MXF_INTEROP )
+ OPAtomUL.Set(Dict::ul(MDD_MXFInterop_OPAtom));
+
+ m_BodyPart.OperationalPattern = OPAtomUL;
+ m_HeaderPart.m_RIP.PairArray.push_back(RIP::Pair(1, m_BodyPart.ThisPartition)); // Second RIP Entry
+
+ UL BodyUL(Dict::ul(MDD_ClosedCompleteBodyPartition));
+ result = m_BodyPart.WriteToFile(m_File, BodyUL);
+ }
- //
- // Index setup
- //
- fpos_t ECoffset = m_File.Tell();
+ if ( ASDCP_SUCCESS(result) )
+ {
+ // Index setup
+ fpos_t ECoffset = m_File.Tell();
- if ( BytesPerEditUnit == 0 )
- m_FooterPart.SetIndexParamsVBR(&m_HeaderPart.m_Primer, EditRate, ECoffset);
- else
- m_FooterPart.SetIndexParamsCBR(&m_HeaderPart.m_Primer, BytesPerEditUnit, EditRate);
+ if ( BytesPerEditUnit == 0 )
+ m_FooterPart.SetIndexParamsVBR(&m_HeaderPart.m_Primer, EditRate, ECoffset);
+ else
+ m_FooterPart.SetIndexParamsCBR(&m_HeaderPart.m_Primer, BytesPerEditUnit, EditRate);
+ }
return result;
}
ASDCP::h__Writer::WriteMXFFooter()
{
// Set top-level file package correctly for OP-Atom
- m_MPTCSequence->Duration = m_FramesWritten;
- m_MPTimecode->Duration = m_FramesWritten;
- m_MPClSequence->Duration = m_FramesWritten;
- m_MPClip->Duration = m_FramesWritten;
- m_FPTCSequence->Duration = m_FramesWritten;
- m_FPTimecode->Duration = m_FramesWritten;
- m_FPClSequence->Duration = m_FramesWritten;
- m_FPClip->Duration = m_FramesWritten;
- m_EssenceDescriptor->ContainerDuration = m_FramesWritten;
+
+ m_MPTCSequence->Duration = m_MPTimecode->Duration = m_MPClSequence->Duration = m_MPClip->Duration =
+ m_FPTCSequence->Duration = m_FPTimecode->Duration = m_FPClSequence->Duration = m_FPClip->Duration =
+ m_EssenceDescriptor->ContainerDuration = m_FramesWritten;
fpos_t here = m_File.Tell();
- m_HeaderPart.m_RIP.PairArray.push_back(RIP::Pair(1, here)); // Third RIP Entry
+ m_HeaderPart.m_RIP.PairArray.push_back(RIP::Pair(0, here)); // Third RIP Entry
m_HeaderPart.FooterPartition = here;
- m_HeaderPart.BodySID = 1;
// re-label the partition
UL OPAtomUL(Dict::ul(MDD_OPAtom));
m_HeaderPart.OperationalPattern = OPAtomUL;
m_HeaderPart.m_Preface->OperationalPattern = m_HeaderPart.OperationalPattern;
+ m_FooterPart.PreviousPartition = m_BodyPart.ThisPartition;
m_FooterPart.OperationalPattern = m_HeaderPart.OperationalPattern;
m_FooterPart.EssenceContainers = m_HeaderPart.EssenceContainers;
m_FooterPart.FooterPartition = here;
{
Result_t result = RESULT_OK;
bool read_mxf = false;
- bool rewrite_mxf = false;
int arg_i = 1;
set_debug_mode(true, true);
read_mxf = true;
arg_i++;
}
- else if ( strcmp(argv[1], "-w") == 0 )
- {
- rewrite_mxf = true;
- arg_i++;
- assert(argc - arg_i == 2);
- }
fprintf(stderr, "Opening file %s\n", argv[arg_i]);
if ( ASDCP_SUCCESS(result) )
result = Header.InitFromFile(Reader);
- // if ( ASDCP_SUCCESS(result) )
Header.Dump(stdout);
if ( ASDCP_SUCCESS(result) )
Index.Dump(stdout);
}
}
- else if ( rewrite_mxf )
- {
- ASDCP::FileReader Reader;
- ASDCP::FileWriter Writer;
- ASDCP::MXF::OPAtomHeader Header;
- ASDCP::MXF::OPAtomIndexFooter Index;
-
- result = Reader.OpenRead(argv[arg_i++]);
-
- if ( ASDCP_SUCCESS(result) )
- result = Header.InitFromFile(Reader);
-
- if ( ASDCP_SUCCESS(result) )
- result = Reader.Seek(Header.FooterPartition);
-
- if ( ASDCP_SUCCESS(result) )
- result = Index.InitFromFile(Reader);
-
- Header.m_Primer.ClearTagList();
-
- if ( ASDCP_SUCCESS(result) )
- result = Writer.OpenWrite(argv[arg_i]);
-
- if ( ASDCP_SUCCESS(result) )
- result = Header.WriteToFile(Writer);
-
-// if ( ASDCP_SUCCESS(result) )
-// result = Index.WriteToFile(Writer);
-
- // essence packets
-
- // index
-
- // RIP
- }
else // dump klv
{
ASDCP::FileReader Reader;