X-Git-Url: https://git.carlh.net/gitweb/?a=blobdiff_plain;f=src%2Fh__Writer.cpp;h=451796654be01e5e0acd649aed43549015cdbf0e;hb=44bc524e3cf74f0903b7fbb51ca2f366f48d3495;hp=cd51391dcd5d6d93f37e080937840102c6433754;hpb=9bfe9676115531eb76649e1ebd5e14b904b53ae2;p=asdcplib.git diff --git a/src/h__Writer.cpp b/src/h__Writer.cpp index cd51391..4517966 100755 --- a/src/h__Writer.cpp +++ b/src/h__Writer.cpp @@ -1,5 +1,5 @@ /* -Copyright (c) 2004-2006, John Hurst +Copyright (c) 2004-2008, John Hurst All rights reserved. Redistribution and use in source and binary forms, with or without @@ -30,22 +30,22 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "AS_DCP_internal.h" -#include "MemIO.h" -#include "Timecode.h" #include "KLV.h" using namespace ASDCP; using namespace ASDCP::MXF; // a magic number identifying asdcplib -#ifndef WM_BUILD_NUMBER -#define WM_BUILD_NUMBER 0x4A48 +#ifndef ASDCP_BUILD_NUMBER +#define ASDCP_BUILD_NUMBER 0x6A68 #endif // -ASDCP::h__Writer::h__Writer() : m_EssenceDescriptor(0), m_FramesWritten(0), m_StreamOffset(0) +ASDCP::h__Writer::h__Writer() : + m_HeaderSize(0), m_EssenceStart(0), + m_EssenceDescriptor(0), m_FramesWritten(0), m_StreamOffset(0) { } @@ -53,24 +53,6 @@ ASDCP::h__Writer::~h__Writer() { } - -const byte_t PictDD_Data[SMPTE_UL_LENGTH] = { - 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01, - 0x01, 0x03, 0x02, 0x02, 0x01, 0x00, 0x00, 0x00 }; - -const byte_t SoundDD_Data[SMPTE_UL_LENGTH] = { - 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01, - 0x01, 0x03, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00 }; - -const byte_t TCDD_Data[SMPTE_UL_LENGTH] = { - 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01, - 0x01, 0x03, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00 }; - -const byte_t DMDD_Data[SMPTE_UL_LENGTH] = { - 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01, - 0x01, 0x03, 0x02, 0x01, 0x10, 0x00, 0x00, 0x00 }; - - // // add DMS CryptographicFramework entry to source package void @@ -86,7 +68,7 @@ AddDMScrypt(Partition& HeaderPart, SourcePackage& Package, WriterInfo& Descr, co Sequence* Seq = new Sequence; HeaderPart.AddChildObject(Seq); NewTrack->Sequence = Seq->InstanceUID; - Seq->DataDefinition = UL(DMDD_Data); + Seq->DataDefinition = UL(Dict::ul(MDD_DescriptiveMetaDataDef)); DMSegment* Segment = new DMSegment; HeaderPart.AddChildObject(Segment); @@ -103,18 +85,16 @@ AddDMScrypt(Partition& HeaderPart, SourcePackage& Package, WriterInfo& Descr, co Context->ContextID.Set(Descr.ContextID); Context->SourceEssenceContainer = WrappingUL; // ?????? - Context->CipherAlgorithm.Set(CipherAlgorithm_AES); - Context->MICAlgorithm.Set( Descr.UsesHMAC ? MICAlgorithm_HMAC_SHA1 : MICAlgorithm_NONE ); + Context->CipherAlgorithm.Set(Dict::ul(MDD_CipherAlgorithm_AES)); + Context->MICAlgorithm.Set( Descr.UsesHMAC ? Dict::ul(MDD_MICAlgorithm_HMAC_SHA1) : Dict::ul(MDD_MICAlgorithm_NONE) ); Context->CryptographicKeyID.Set(Descr.CryptographicKeyID); } // -Result_t -ASDCP::h__Writer::WriteMXFHeader(const std::string& PackageLabel, const UL& WrappingUL, - const MXF::Rational& EditRate, - ui32_t TCFrameRate, ui32_t BytesPerEditUnit) +void +ASDCP::h__Writer::InitHeader() { - ASDCP_TEST_NULL(m_EssenceDescriptor); + assert(m_EssenceDescriptor); m_HeaderPart.m_Primer.ClearTagList(); m_HeaderPart.m_Preface = new Preface; @@ -122,9 +102,14 @@ ASDCP::h__Writer::WriteMXFHeader(const std::string& PackageLabel, const UL& Wrap // 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(OP1aUL); + 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 + + // 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 @@ -133,18 +118,80 @@ ASDCP::h__Writer::WriteMXFHeader(const std::string& PackageLabel, const UL& Wrap m_HeaderPart.AddChildObject(Ident); m_HeaderPart.m_Preface->Identifications.push_back(Ident->InstanceUID); - Ident->ThisGenerationUID.GenRandomValue(); + 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 = WM_PLATFORM; - Ident->ToolkitVersion.Release = VersionType::RL_DEVELOPMENT; + Ident->Platform = ASDCP_PLATFORM; Ident->ToolkitVersion.Major = VERSION_MAJOR; Ident->ToolkitVersion.Minor = VERSION_APIMINOR; Ident->ToolkitVersion.Patch = VERSION_IMPMINOR; - Ident->ToolkitVersion.Build = WM_BUILD_NUMBER; + Ident->ToolkitVersion.Build = ASDCP_BUILD_NUMBER; + Ident->ToolkitVersion.Release = VersionType::RL_RELEASE; +} + +// +template +struct TrackSet +{ + MXF::Track* Track; + MXF::Sequence* Sequence; + ClipT* Clip; + TrackSet() : Track(0), Sequence(0), Clip(0) {} +}; + +// +template +TrackSet +CreateTrackAndSequence(OPAtomHeader& Header, PackageT& Package, const std::string TrackName, + const MXF::Rational& EditRate, const UL& Definition, ui32_t TrackID) +{ + TrackSet NewTrack; + + NewTrack.Track = new Track; + Header.AddChildObject(NewTrack.Track); + NewTrack.Track->EditRate = EditRate; + Package.Tracks.push_back(NewTrack.Track->InstanceUID); + NewTrack.Track->TrackID = TrackID; + NewTrack.Track->TrackName = TrackName.c_str(); + + NewTrack.Sequence = new Sequence; + Header.AddChildObject(NewTrack.Sequence); + NewTrack.Track->Sequence = NewTrack.Sequence->InstanceUID; + NewTrack.Sequence->DataDefinition = Definition; + + return NewTrack; +} + +// +template +TrackSet +CreateTimecodeTrack(OPAtomHeader& Header, PackageT& Package, + const MXF::Rational& EditRate, ui32_t TCFrameRate, ui64_t TCStart) +{ + UL TCUL(Dict::ul(MDD_TimecodeDataDef)); + + TrackSet NewTrack = CreateTrackAndSequence(Header, Package, "Timecode Track", EditRate, TCUL, 1); + + NewTrack.Clip = new TimecodeComponent; + Header.AddChildObject(NewTrack.Clip); + NewTrack.Sequence->StructuralComponents.push_back(NewTrack.Clip->InstanceUID); + NewTrack.Clip->RoundedTimecodeBase = TCFrameRate; + NewTrack.Clip->StartTimecode = TCStart; + NewTrack.Clip->DataDefinition = TCUL; + + return NewTrack; +} + + +// +void +ASDCP::h__Writer::AddSourceClip(const MXF::Rational& EditRate, ui32_t TCFrameRate, + const std::string& TrackName, const UL& DataDefinition, + const std::string& PackageLabel) +{ // ContentStorage* Storage = new ContentStorage; m_HeaderPart.AddChildObject(Storage); @@ -156,160 +203,245 @@ ASDCP::h__Writer::WriteMXFHeader(const std::string& PackageLabel, const UL& Wrap ECD->IndexSID = 129; ECD->BodySID = 1; + UUID assetUUID(m_Info.AssetUUID); + UMID SourcePackageUMID, MaterialPackageUMID; + SourcePackageUMID.MakeUMID(0x0f, assetUUID); + MaterialPackageUMID.MakeUMID(0x0f); // unidentified essence + // // Material Package // - UMID PackageUMID; - PackageUMID.MakeUMID(0x0d); // Using mixed type. What is the actual type? - m_MaterialPackage = new MaterialPackage; m_MaterialPackage->Name = "AS-DCP Material Package"; - m_MaterialPackage->PackageUID = PackageUMID; - + m_MaterialPackage->PackageUID = MaterialPackageUMID; m_HeaderPart.AddChildObject(m_MaterialPackage); Storage->Packages.push_back(m_MaterialPackage->InstanceUID); - // Timecode Track - Track* NewTrack = new Track; - m_HeaderPart.AddChildObject(NewTrack); - NewTrack->EditRate = EditRate; - m_MaterialPackage->Tracks.push_back(NewTrack->InstanceUID); - NewTrack->TrackID = 1; - NewTrack->TrackName = "Timecode Track"; + TrackSet MPTCTrack = CreateTimecodeTrack(m_HeaderPart, *m_MaterialPackage, + EditRate, TCFrameRate, 0); + m_DurationUpdateList.push_back(&(MPTCTrack.Sequence->Duration)); + m_DurationUpdateList.push_back(&(MPTCTrack.Clip->Duration)); - Sequence* Seq = new Sequence; - m_HeaderPart.AddChildObject(Seq); - NewTrack->Sequence = Seq->InstanceUID; - Seq->DataDefinition = UL(TCDD_Data); + TrackSet MPTrack = CreateTrackAndSequence(m_HeaderPart, *m_MaterialPackage, + TrackName, EditRate, DataDefinition, 2); + m_DurationUpdateList.push_back(&(MPTrack.Sequence->Duration)); - m_MPTimecode = new TimecodeComponent; - m_HeaderPart.AddChildObject(m_MPTimecode); - Seq->StructuralComponents.push_back(m_MPTimecode->InstanceUID); - m_MPTimecode->RoundedTimecodeBase = TCFrameRate; - m_MPTimecode->StartTimecode = ui64_C(0); - m_MPTimecode->DataDefinition = UL(TCDD_Data); - - // Essence Track - NewTrack = new Track; - m_HeaderPart.AddChildObject(NewTrack); - NewTrack->EditRate = EditRate; - m_MaterialPackage->Tracks.push_back(NewTrack->InstanceUID); - NewTrack->TrackID = 2; - NewTrack->TrackName = "Essence Track"; - - Seq = new Sequence; - m_HeaderPart.AddChildObject(Seq); - NewTrack->Sequence = Seq->InstanceUID; - - m_MPClip = new SourceClip; - m_HeaderPart.AddChildObject(m_MPClip); - Seq->StructuralComponents.push_back(m_MPClip->InstanceUID); + MPTrack.Clip = new SourceClip; + m_HeaderPart.AddChildObject(MPTrack.Clip); + MPTrack.Sequence->StructuralComponents.push_back(MPTrack.Clip->InstanceUID); + MPTrack.Clip->DataDefinition = DataDefinition; + MPTrack.Clip->SourcePackageID = SourcePackageUMID; + MPTrack.Clip->SourceTrackID = 2; + m_DurationUpdateList.push_back(&(MPTrack.Clip->Duration)); + // // File (Source) Package // + m_FilePackage = new SourcePackage; + m_FilePackage->Name = PackageLabel.c_str(); + m_FilePackage->PackageUID = SourcePackageUMID; + ECD->LinkedPackageUID = SourcePackageUMID; + + m_HeaderPart.AddChildObject(m_FilePackage); + Storage->Packages.push_back(m_FilePackage->InstanceUID); + + TrackSet FPTCTrack = CreateTimecodeTrack(m_HeaderPart, *m_FilePackage, + EditRate, TCFrameRate, ui64_C(3600) * TCFrameRate); + m_DurationUpdateList.push_back(&(FPTCTrack.Sequence->Duration)); + m_DurationUpdateList.push_back(&(FPTCTrack.Clip->Duration)); + + TrackSet FPTrack = CreateTrackAndSequence(m_HeaderPart, *m_FilePackage, + TrackName, EditRate, DataDefinition, 2); + m_DurationUpdateList.push_back(&(FPTrack.Sequence->Duration)); + + FPTrack.Clip = new SourceClip; + m_HeaderPart.AddChildObject(FPTrack.Clip); + FPTrack.Sequence->StructuralComponents.push_back(FPTrack.Clip->InstanceUID); + FPTrack.Clip->DataDefinition = DataDefinition; + + // for now we do not allow setting this value, so all files will be 'original' + FPTrack.Clip->SourceTrackID = 0; + FPTrack.Clip->SourcePackageID = NilUMID; + m_DurationUpdateList.push_back(&(FPTrack.Clip->Duration)); + + m_EssenceDescriptor->LinkedTrackID = FPTrack.Track->TrackID; +} + +// +void +ASDCP::h__Writer::AddDMSegment(const MXF::Rational& EditRate, ui32_t TCFrameRate, + const std::string& TrackName, const UL& DataDefinition, + const std::string& PackageLabel) +{ + // + ContentStorage* Storage = new ContentStorage; + m_HeaderPart.AddChildObject(Storage); + m_HeaderPart.m_Preface->ContentStorage = Storage->InstanceUID; + + EssenceContainerData* ECD = new EssenceContainerData; + m_HeaderPart.AddChildObject(ECD); + Storage->EssenceContainerData.push_back(ECD->InstanceUID); + ECD->IndexSID = 129; + ECD->BodySID = 1; + UUID assetUUID(m_Info.AssetUUID); - PackageUMID.MakeUMID(0x0f, assetUUID); + UMID SourcePackageUMID, MaterialPackageUMID; + SourcePackageUMID.MakeUMID(0x0f, assetUUID); + MaterialPackageUMID.MakeUMID(0x0f); // unidentified essence + // + // Material Package + // + m_MaterialPackage = new MaterialPackage; + m_MaterialPackage->Name = "AS-DCP Material Package"; + m_MaterialPackage->PackageUID = MaterialPackageUMID; + m_HeaderPart.AddChildObject(m_MaterialPackage); + Storage->Packages.push_back(m_MaterialPackage->InstanceUID); + + TrackSet MPTCTrack = CreateTimecodeTrack(m_HeaderPart, *m_MaterialPackage, + EditRate, TCFrameRate, 0); + m_DurationUpdateList.push_back(&(MPTCTrack.Sequence->Duration)); + m_DurationUpdateList.push_back(&(MPTCTrack.Clip->Duration)); + + TrackSet MPTrack = CreateTrackAndSequence(m_HeaderPart, *m_MaterialPackage, + TrackName, EditRate, DataDefinition, 2); + m_DurationUpdateList.push_back(&(MPTrack.Sequence->Duration)); + + MPTrack.Clip = new DMSegment; + m_HeaderPart.AddChildObject(MPTrack.Clip); + MPTrack.Sequence->StructuralComponents.push_back(MPTrack.Clip->InstanceUID); + MPTrack.Clip->DataDefinition = DataDefinition; + // MPTrack.Clip->SourcePackageID = SourcePackageUMID; + // MPTrack.Clip->SourceTrackID = 2; + m_DurationUpdateList.push_back(&(MPTrack.Clip->Duration)); + + + // + // File (Source) Package + // m_FilePackage = new SourcePackage; m_FilePackage->Name = PackageLabel.c_str(); - m_FilePackage->PackageUID = PackageUMID; - ECD->LinkedPackageUID = PackageUMID; - m_MPClip->SourcePackageID = PackageUMID; - m_MPClip->SourceTrackID = 1; + m_FilePackage->PackageUID = SourcePackageUMID; + ECD->LinkedPackageUID = SourcePackageUMID; m_HeaderPart.AddChildObject(m_FilePackage); Storage->Packages.push_back(m_FilePackage->InstanceUID); - // Timecode Track - NewTrack = new Track; - m_HeaderPart.AddChildObject(NewTrack); - NewTrack->EditRate = EditRate; - m_FilePackage->Tracks.push_back(NewTrack->InstanceUID); - NewTrack->TrackID = 1; - NewTrack->TrackName = "Timecode Track"; - - Seq = new Sequence; - m_HeaderPart.AddChildObject(Seq); - NewTrack->Sequence = Seq->InstanceUID; - Seq->DataDefinition = UL(TCDD_Data); + TrackSet FPTCTrack = CreateTimecodeTrack(m_HeaderPart, *m_FilePackage, + EditRate, TCFrameRate, ui64_C(3600) * TCFrameRate); + m_DurationUpdateList.push_back(&(FPTCTrack.Sequence->Duration)); + m_DurationUpdateList.push_back(&(FPTCTrack.Clip->Duration)); - m_FPTimecode = new TimecodeComponent; - m_HeaderPart.AddChildObject(m_FPTimecode); - Seq->StructuralComponents.push_back(m_FPTimecode->InstanceUID); - m_FPTimecode->RoundedTimecodeBase = TCFrameRate; - m_FPTimecode->StartTimecode = ui64_C(86400); // 01:00:00:00 - m_FPTimecode->DataDefinition = UL(TCDD_Data); + TrackSet FPTrack = CreateTrackAndSequence(m_HeaderPart, *m_FilePackage, + TrackName, EditRate, DataDefinition, 2); + m_DurationUpdateList.push_back(&(FPTrack.Sequence->Duration)); - // Essence Track - NewTrack = new Track; - m_HeaderPart.AddChildObject(NewTrack); - NewTrack->EditRate = EditRate; - m_FilePackage->Tracks.push_back(NewTrack->InstanceUID); - NewTrack->TrackID = 2; - NewTrack->TrackName = "Essence Track"; - - Seq = new Sequence; - m_HeaderPart.AddChildObject(Seq); - NewTrack->Sequence = Seq->InstanceUID; + FPTrack.Clip = new DMSegment; + m_HeaderPart.AddChildObject(FPTrack.Clip); + FPTrack.Sequence->StructuralComponents.push_back(FPTrack.Clip->InstanceUID); + FPTrack.Clip->DataDefinition = DataDefinition; + FPTrack.Clip->EventComment = "D-Cinema Timed Text"; - m_FPClip = new SourceClip; - m_HeaderPart.AddChildObject(m_FPClip); - Seq->StructuralComponents.push_back(m_FPClip->InstanceUID); + m_DurationUpdateList.push_back(&(FPTrack.Clip->Duration)); + m_EssenceDescriptor->LinkedTrackID = FPTrack.Track->TrackID; +} +// +void +ASDCP::h__Writer::AddEssenceDescriptor(const UL& WrappingUL) +{ // // Essence Descriptor // m_EssenceDescriptor->EssenceContainer = WrappingUL; - m_EssenceDescriptor->LinkedTrackID = NewTrack->TrackID; - - // link the Material Package to the File Package ????????????????????????????????? - Seq->StructuralComponents.push_back(NewTrack->InstanceUID); m_HeaderPart.m_Preface->PrimaryPackage = m_FilePackage->InstanceUID; // - // Encryption Descriptor + // Essence Descriptors // + UL GenericContainerUL(Dict::ul(MDD_GCMulti)); + m_HeaderPart.EssenceContainers.push_back(GenericContainerUL); + if ( m_Info.EncryptedEssence ) { - UL CryptEssenceUL(WrappingUL_Data_Crypt); + 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(CryptoFrameworkUL_Data)); + m_HeaderPart.m_Preface->DMSchemes.push_back(UL(Dict::ul(MDD_CryptographicFrameworkLabel))); AddDMScrypt(m_HeaderPart, *m_FilePackage, m_Info, WrappingUL); } else { - UL GCUL(GCMulti_Data); - m_HeaderPart.EssenceContainers.push_back(GCUL); 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, HeaderPadding); - - // - // Body Partition - // + std::list::iterator sdli = m_EssenceSubDescriptorList.begin(); + for ( ; sdli != m_EssenceSubDescriptorList.end(); sdli++ ) + m_HeaderPart.AddChildObject(*sdli); + m_FilePackage->Descriptor = m_EssenceDescriptor->InstanceUID; +} - // - // Index setup - // - fpos_t ECoffset = m_File.Tell(); +// +Result_t +ASDCP::h__Writer::CreateBodyPart(const MXF::Rational& EditRate, ui32_t BytesPerEditUnit) +{ + Result_t result = RESULT_OK; - if ( BytesPerEditUnit == 0 ) - m_FooterPart.SetIndexParamsVBR(&m_HeaderPart.m_Primer, EditRate, ECoffset); + // create a body partition if we're writing proper 429-3/OP-Atom + if ( m_Info.LabelSetType == LS_MXF_SMPTE ) + { + // Body Partition + m_BodyPart.EssenceContainers = m_HeaderPart.EssenceContainers; + m_BodyPart.ThisPartition = m_File.Tell(); + m_BodyPart.BodySID = 1; + UL OPAtomUL(Dict::ul(MDD_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); + } else - m_FooterPart.SetIndexParamsCBR(&m_HeaderPart.m_Primer, BytesPerEditUnit, EditRate); + { + m_HeaderPart.BodySID = 1; + } + + if ( ASDCP_SUCCESS(result) ) + { + // Index setup + Kumu::fpos_t ECoffset = m_File.Tell(); + m_FooterPart.IndexSID = 129; + + if ( BytesPerEditUnit == 0 ) + m_FooterPart.SetIndexParamsVBR(&m_HeaderPart.m_Primer, EditRate, ECoffset); + else + 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& DataDefinition, + const MXF::Rational& EditRate, ui32_t TCFrameRate, ui32_t BytesPerEditUnit) +{ + InitHeader(); + AddSourceClip(EditRate, TCFrameRate, TrackName, DataDefinition, PackageLabel); + AddEssenceDescriptor(WrappingUL); + + Result_t result = m_HeaderPart.WriteToFile(m_File, m_HeaderSize); + + if ( KM_SUCCESS(result) ) + result = CreateBodyPart(EditRate, BytesPerEditUnit); + + return result; +} // standard method of writing a plaintext or encrypted frame @@ -317,11 +449,11 @@ Result_t ASDCP::h__Writer::WriteEKLVPacket(const ASDCP::FrameBuffer& FrameBuf, const byte_t* EssenceUL, AESEncContext* Ctx, HMACContext* HMAC) { - Result_t result; + Result_t result = RESULT_OK; IntegrityPack IntPack; byte_t overhead[128]; - MemIOWriter Overhead(overhead, 128); + Kumu::MemIOWriter Overhead(overhead, 128); if ( FrameBuf.Size() == 0 ) { @@ -349,7 +481,10 @@ ASDCP::h__Writer::WriteEKLVPacket(const ASDCP::FrameBuffer& FrameBuf, const byte if ( ASDCP_SUCCESS(result) ) { // write UL - Overhead.WriteRaw((byte_t*)CryptEssenceUL_Data, klv_key_size); + if ( m_Info.LabelSetType == LS_MXF_INTEROP ) + Overhead.WriteRaw(Dict::ul(MDD_MXFInterop_CryptEssence), SMPTE_UL_LENGTH); + else + Overhead.WriteRaw(Dict::ul(MDD_CryptEssence), SMPTE_UL_LENGTH); // construct encrypted triplet header ui32_t ETLength = klv_cryptinfo_size + m_CtFrameBuf.Size(); @@ -357,25 +492,25 @@ ASDCP::h__Writer::WriteEKLVPacket(const ASDCP::FrameBuffer& FrameBuf, const byte if ( m_Info.UsesHMAC ) ETLength += klv_intpack_size; else - ETLength += (klv_length_size * 3); // for empty intpack + ETLength += (MXF_BER_LENGTH * 3); // for empty intpack - Overhead.WriteBER(ETLength, klv_length_size); // write encrypted triplet length - Overhead.WriteBER(UUIDlen, klv_length_size); // write ContextID length + Overhead.WriteBER(ETLength, MXF_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), klv_length_size); // write PlaintextOffset length + Overhead.WriteBER(sizeof(ui64_t), MXF_BER_LENGTH); // write PlaintextOffset length Overhead.WriteUi64BE(FrameBuf.PlaintextOffset()); // write PlaintextOffset - Overhead.WriteBER(klv_key_size, klv_length_size); // write essence UL length - Overhead.WriteRaw((byte_t*)EssenceUL, klv_key_size); // write the essence UL - Overhead.WriteBER(sizeof(ui64_t), klv_length_size); // write SourceLength length + 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(), klv_length_size); // write ESV length + Overhead.WriteBER(m_CtFrameBuf.Size(), MXF_BER_LENGTH); // write ESV length - result = m_File.Writev(Overhead.Data(), Overhead.Size()); + result = m_File.Writev(Overhead.Data(), Overhead.Length()); } if ( ASDCP_SUCCESS(result) ) { - m_StreamOffset += Overhead.Size(); + m_StreamOffset += Overhead.Length(); // write encrypted source value result = m_File.Writev((byte_t*)m_CtFrameBuf.RoData(), m_CtFrameBuf.Size()); } @@ -385,7 +520,7 @@ ASDCP::h__Writer::WriteEKLVPacket(const ASDCP::FrameBuffer& FrameBuf, const byte m_StreamOffset += m_CtFrameBuf.Size(); byte_t hmoverhead[512]; - MemIOWriter HMACOverhead(hmoverhead, 512); + Kumu::MemIOWriter HMACOverhead(hmoverhead, 512); // write the HMAC if ( m_Info.UsesHMAC ) @@ -395,25 +530,25 @@ ASDCP::h__Writer::WriteEKLVPacket(const ASDCP::FrameBuffer& FrameBuf, const byte 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, klv_length_size); + HMACOverhead.WriteBER(0, MXF_BER_LENGTH); } // write HMAC - result = m_File.Writev(HMACOverhead.Data(), HMACOverhead.Size()); - m_StreamOffset += HMACOverhead.Size(); + result = m_File.Writev(HMACOverhead.Data(), HMACOverhead.Length()); + m_StreamOffset += HMACOverhead.Length(); } } else { - Overhead.WriteRaw((byte_t*)EssenceUL, klv_key_size); - Overhead.WriteBER(FrameBuf.Size(), klv_length_size); - result = m_File.Writev(Overhead.Data(), Overhead.Size()); + Overhead.WriteRaw((byte_t*)EssenceUL, SMPTE_UL_LENGTH); + Overhead.WriteBER(FrameBuf.Size(), MXF_BER_LENGTH); + 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.Size() + FrameBuf.Size(); + m_StreamOffset += Overhead.Length() + FrameBuf.Size(); } if ( ASDCP_SUCCESS(result) ) @@ -429,18 +564,29 @@ Result_t ASDCP::h__Writer::WriteMXFFooter() { // Set top-level file package correctly for OP-Atom - m_MPTimecode->Duration = m_FramesWritten; - m_MPClip->Duration = m_FramesWritten; - m_FPTimecode->Duration = m_FramesWritten; - m_FPClip->Duration = m_FramesWritten; + + // m_MPTCSequence->Duration = m_MPTimecode->Duration = m_MPClSequence->Duration = m_MPClip->Duration = + // m_FPTCSequence->Duration = m_FPTimecode->Duration = m_FPClSequence->Duration = m_FPClip->Duration = + + DurationElementList_t::iterator dli = m_DurationUpdateList.begin(); + + for (; dli != m_DurationUpdateList.end(); dli++ ) + **dli = m_FramesWritten; + m_EssenceDescriptor->ContainerDuration = m_FramesWritten; + m_FooterPart.PreviousPartition = m_HeaderPart.m_RIP.PairArray.back().ByteOffset; - fpos_t here = m_File.Tell(); - m_HeaderPart.m_RIP.PairArray.push_back(RIP::Pair(1, here)); // Third RIP Entry + 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; - m_HeaderPart.BodySID = 1; - m_HeaderPart.IndexSID = m_FooterPart.IndexSID; - m_HeaderPart.OperationalPattern = UL(OPAtomUL); + + // re-label the partition + UL OPAtomUL(Dict::ul(MDD_OPAtom)); + + if ( m_Info.LabelSetType == LS_MXF_INTEROP ) + OPAtomUL.Set(Dict::ul(MDD_MXFInterop_OPAtom)); + + m_HeaderPart.OperationalPattern = OPAtomUL; m_HeaderPart.m_Preface->OperationalPattern = m_HeaderPart.OperationalPattern; m_FooterPart.OperationalPattern = m_HeaderPart.OperationalPattern; @@ -457,7 +603,7 @@ ASDCP::h__Writer::WriteMXFFooter() result = m_File.Seek(0); if ( ASDCP_SUCCESS(result) ) - result = m_HeaderPart.WriteToFile(m_File, HeaderPadding); + result = m_HeaderPart.WriteToFile(m_File, m_HeaderSize); m_File.Close(); return result;