summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorjhurst <jhurst@cinecert.com>2013-12-15 23:34:13 +0000
committerjhurst <>2013-12-15 23:34:13 +0000
commit7f373b689817ee70fbe5d6a14cb0512b5260f77c (patch)
tree0b182f46691f1420e18be08ea1952a818c546f94 /src
parent1f41555bcf96369227cda526e36196fe512f464e (diff)
o Added preliminary support for timed-text wrapping for AS-02. This
work will require changes in SMPTE ST 429-5 and perhaps other standards work, so files created with this implementation are "speculative". Publication of the revised ST 429-5 may not occur until early 2015. o Moved LocalFilenameResolver into the AS_DCP public API so that it can be used by other modules including AS-02. o Fixed wave wrapping UL in clip-wrapped AS-02 files. Renamed some UL constants to reflect "clip" or "frame" wrapping. o Re-factored JP2K_PDesc_to_MD() and MD_to_JP2K_PDesc() to work with GenericPictureEssenceDescriptor objects. o Fixed a bug that was suppressing PictureComponentSizing, CodingStyleDefault and QuantizationDefault when writing the essence descriptor in a JP2K file (AS-DCP and AS-02). o Fixed the version byte on the following UL values: StereoscopicPictureSubDescriptor GenericPictureEssenceDescriptor_ColorPrimaries GenericPictureEssenceDescriptor_ActiveHeight GenericPictureEssenceDescriptor_ActiveWidth GenericPictureEssenceDescriptor_ActiveXOffset GenericPictureEssenceDescriptor_ActiveYOffset o Added some essence descriptor options to as-02-wrap. o Added TTML timed-text wrapping option to as-02-wrap. o Changed bit rate display in asdcp-info from mebi-bits/s to mega-bits/s. o Added "SMPTE" / "Interop" format type display to asdcp-info. o Modified asdcp-wrap to assume -L when wrapping timed-text (since there is no MXF text wrapping for Interop.) o Fixed missing-index-partion bugs for AS-02 files.
Diffstat (limited to 'src')
-rw-r--r--src/AS_02.h146
-rw-r--r--src/AS_02_JP2K.cpp2
-rw-r--r--src/AS_02_PCM.cpp5
-rwxr-xr-xsrc/AS_DCP.h16
-rw-r--r--src/AS_DCP_DCData.cpp2
-rwxr-xr-xsrc/AS_DCP_JP2K.cpp232
-rwxr-xr-xsrc/AS_DCP_MPEG2.cpp2
-rwxr-xr-xsrc/AS_DCP_PCM.cpp2
-rw-r--r--src/AS_DCP_TimedText.cpp2
-rwxr-xr-xsrc/AS_DCP_internal.h16
-rw-r--r--src/MDD.cpp26
-rwxr-xr-xsrc/MDD.h11
-rwxr-xr-xsrc/MXF.cpp27
-rw-r--r--src/Makefile.am2
-rw-r--r--src/TimedText_Parser.cpp96
-rwxr-xr-xsrc/as-02-wrap.cpp191
-rwxr-xr-xsrc/asdcp-info.cpp7
-rwxr-xr-xsrc/asdcp-wrap.cpp10
-rw-r--r--src/h__02_Reader.cpp33
-rw-r--r--src/h__02_Writer.cpp15
20 files changed, 518 insertions, 325 deletions
diff --git a/src/AS_02.h b/src/AS_02.h
index e534dd4..3437152 100644
--- a/src/AS_02.h
+++ b/src/AS_02.h
@@ -314,6 +314,152 @@ namespace AS_02
};
} // namespace PCM
+ //---------------------------------------------------------------------------------
+ //
+ namespace TimedText
+ {
+ using ASDCP::TimedText::TimedTextDescriptor;
+ using ASDCP::TimedText::TimedTextResourceDescriptor;
+ using ASDCP::TimedText::ResourceList_t;
+
+ //
+ class ST2052_TextParser
+ {
+ class h__TextParser;
+ ASDCP::mem_ptr<h__TextParser> m_Parser;
+ ASDCP_NO_COPY_CONSTRUCT(ST2052_TextParser);
+
+ public:
+ ST2052_TextParser();
+ virtual ~ST2052_TextParser();
+
+ // Opens an XML file for reading, parses data to provide a complete
+ // set of stream metadata for the MXFWriter below.
+ Result_t OpenRead(const std::string& filename) const;
+
+ // Parse an XML string
+ Result_t OpenRead(const std::string& xml_doc, const std::string& filename) const;
+
+ // Fill a TimedTextDescriptor struct with the values from the file's contents.
+ // Returns RESULT_INIT if the file is not open.
+ Result_t FillTimedTextDescriptor(ASDCP::TimedText::TimedTextDescriptor&) const;
+
+ // Reads the complete Timed Text Resource into the given string.
+ Result_t ReadTimedTextResource(std::string&) const;
+
+ // Reads the Ancillary Resource having the given ID. Fails if the buffer
+ // is too small or the resource does not exist. The optional Resolver
+ // argument can be provided which will be used to retrieve the resource
+ // having a particulat UUID. If a Resolver is not supplied, the default
+ // internal resolver will return the contents of the file having the UUID
+ // as the filename. The filename must exist in the same directory as the
+ // XML file opened with OpenRead().
+ Result_t ReadAncillaryResource(const Kumu::UUID&, ASDCP::TimedText::FrameBuffer&,
+ const ASDCP::TimedText::IResourceResolver* Resolver = 0) const;
+ };
+
+ //
+ class MXFWriter
+ {
+ class h__Writer;
+ ASDCP::mem_ptr<h__Writer> m_Writer;
+ ASDCP_NO_COPY_CONSTRUCT(MXFWriter);
+
+ public:
+ MXFWriter();
+ virtual ~MXFWriter();
+
+ // Warning: direct manipulation of MXF structures can interfere
+ // with the normal operation of the wrapper. Caveat emptor!
+ 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
+ // in the essence descriptor.
+ Result_t OpenWrite(const std::string& filename, const ASDCP::WriterInfo&,
+ const ASDCP::TimedText::TimedTextDescriptor&, ui32_t HeaderSize = 16384);
+
+ // Writes the Timed-Text Resource to the MXF file. The file must be UTF-8
+ // encoded. If the optional AESEncContext argument is present, the essence
+ // is encrypted prior to writing. Fails if the file is not open, is finalized,
+ // or an operating system error occurs.
+ // This method may only be called once, and it must be called before any
+ // call to WriteAncillaryResource(). RESULT_STATE will be returned if these
+ // conditions are not met.
+ Result_t WriteTimedTextResource(const std::string& XMLDoc, ASDCP::AESEncContext* = 0, ASDCP::HMACContext* = 0);
+
+ // Writes an Ancillary Resource to the MXF file. If the optional AESEncContext
+ // argument is present, the essence is encrypted prior to writing.
+ // Fails if the file is not open, is finalized, or an operating system
+ // error occurs. RESULT_STATE will be returned if the method is called before
+ // WriteTimedTextResource()
+ Result_t WriteAncillaryResource(const ASDCP::TimedText::FrameBuffer&, ASDCP::AESEncContext* = 0, ASDCP::HMACContext* = 0);
+
+ // Closes the MXF file, writing the index and revised header.
+ Result_t Finalize();
+ };
+
+ //
+ class MXFReader
+ {
+ class h__Reader;
+ ASDCP::mem_ptr<h__Reader> m_Reader;
+ ASDCP_NO_COPY_CONSTRUCT(MXFReader);
+
+ public:
+ MXFReader();
+ virtual ~MXFReader();
+
+ // Warning: direct manipulation of MXF structures can interfere
+ // with the normal operation of the wrapper. Caveat emptor!
+ 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.
+ Result_t OpenRead(const std::string& filename) const;
+
+ // Returns RESULT_INIT if the file is not open.
+ Result_t Close() const;
+
+ // Fill a TimedTextDescriptor struct with the values from the file's header.
+ // Returns RESULT_INIT if the file is not open.
+ Result_t FillTimedTextDescriptor(ASDCP::TimedText::TimedTextDescriptor&) const;
+
+ // Fill a WriterInfo struct with the values from the file's header.
+ // Returns RESULT_INIT if the file is not open.
+ Result_t FillWriterInfo(ASDCP::WriterInfo&) const;
+
+ // Reads the complete Timed Text Resource into the given string. Fails if the resource
+ // is encrypted and AESDecContext is NULL (use the following method to retrieve the
+ // raw ciphertet block).
+ Result_t ReadTimedTextResource(std::string&, ASDCP::AESDecContext* = 0, ASDCP::HMACContext* = 0) const;
+
+ // Reads the complete Timed Text Resource from the MXF file. If the optional AESEncContext
+ // argument is present, the resource is decrypted after reading. If the MXF
+ // file is encrypted and the AESDecContext argument is NULL, the frame buffer
+ // will contain the ciphertext frame data. If the HMACContext argument is
+ // not NULL, the HMAC will be calculated (if the file supports it).
+ // Returns RESULT_INIT if the file is not open, failure if the frame number is
+ // out of range, or if optional decrypt or HAMC operations fail.
+ Result_t ReadTimedTextResource(ASDCP::TimedText::FrameBuffer&, ASDCP::AESDecContext* = 0, ASDCP::HMACContext* = 0) const;
+
+ // Reads the timed-text resource having the given UUID from the MXF file. If the
+ // optional AESEncContext argument is present, the resource is decrypted after
+ // reading. If the MXF file is encrypted and the AESDecContext argument is NULL,
+ // the frame buffer will contain the ciphertext frame data. If the HMACContext
+ // argument is not NULL, the HMAC will be calculated (if the file supports it).
+ // Returns RESULT_INIT if the file is not open, failure if the frame number is
+ // out of range, or if optional decrypt or HAMC operations fail.
+ Result_t ReadAncillaryResource(const Kumu::UUID&, ASDCP::TimedText::FrameBuffer&, ASDCP::AESDecContext* = 0, ASDCP::HMACContext* = 0) const;
+
+ // Print debugging information to stream
+ void DumpHeaderMetadata(FILE* = 0) const;
+ void DumpIndex(FILE* = 0) const;
+ };
+ } // namespace TimedText
} // namespace AS_02
diff --git a/src/AS_02_JP2K.cpp b/src/AS_02_JP2K.cpp
index 79ea382..a8eff1a 100644
--- a/src/AS_02_JP2K.cpp
+++ b/src/AS_02_JP2K.cpp
@@ -331,7 +331,7 @@ AS_02::JP2K::MXFWriter::h__Writer::SetSourceStream(const std::string& label, con
if ( KM_SUCCESS(result) )
{
- result = WriteAS02Header(label, UL(m_Dict->ul(MDD_JPEG_2000Wrapping)),
+ result = WriteAS02Header(label, UL(m_Dict->ul(MDD_JPEG_2000WrappingFrame)),
PICT_DEF_LABEL, UL(m_EssenceUL), UL(m_Dict->ul(MDD_PictureDataDef)),
edit_rate, derive_timecode_rate_from_edit_rate(edit_rate));
}
diff --git a/src/AS_02_PCM.cpp b/src/AS_02_PCM.cpp
index 512bcdb..2ffc45e 100644
--- a/src/AS_02_PCM.cpp
+++ b/src/AS_02_PCM.cpp
@@ -421,7 +421,7 @@ AS_02::PCM::MXFWriter::h__Writer::SetSourceStream(const ASDCP::Rational& edit_ra
m_SamplesPerFrame = AS_02::MXF::CalcSamplesPerFrame(*m_WaveAudioDescriptor, edit_rate);
m_WaveAudioDescriptor->ContainerDuration = 0;
- result = WriteAS02Header(PCM_PACKAGE_LABEL, UL(m_Dict->ul(MDD_WAVWrapping)),
+ result = WriteAS02Header(PCM_PACKAGE_LABEL, UL(m_Dict->ul(MDD_WAVWrappingClip)),
SOUND_DEF_LABEL, UL(m_EssenceUL), UL(m_Dict->ul(MDD_SoundDataDef)),
m_EssenceDescriptor->SampleRate, derive_timecode_rate_from_edit_rate(edit_rate), m_BytesPerFrame);
}
@@ -488,6 +488,9 @@ AS_02::PCM::MXFWriter::h__Writer::Finalize()
if ( KM_SUCCESS(result) )
{
m_FramesWritten = m_FramesWritten * m_SamplesPerFrame;
+ m_IndexWriter.ThisPartition = m_File.Tell();
+ m_IndexWriter.WriteToFile(m_File);
+ m_RIP.PairArray.push_back(RIP::Pair(0, m_IndexWriter.ThisPartition));
WriteAS02Footer();
}
diff --git a/src/AS_DCP.h b/src/AS_DCP.h
index 7ef83e4..6f99698 100755
--- a/src/AS_DCP.h
+++ b/src/AS_DCP.h
@@ -1449,6 +1449,8 @@ namespace ASDCP {
void Dump(FILE* = 0, ui32_t dump_bytes = 0) const;
};
+ // An abstract base for a lookup service that returns the resource data
+ // identified by the given ancillary resource id.
//
class IResourceResolver
{
@@ -1457,6 +1459,20 @@ namespace ASDCP {
virtual Result_t ResolveRID(const byte_t* uuid, FrameBuffer&) const = 0; // return data for RID
};
+ // Resolves resource references by testing the named directory for file names containing
+ // the respective UUID.
+ //
+ class LocalFilenameResolver : public ASDCP::TimedText::IResourceResolver
+ {
+ std::string m_Dirname;
+ ASDCP_NO_COPY_CONSTRUCT(LocalFilenameResolver);
+
+ public:
+ LocalFilenameResolver();
+ Result_t OpenRead(const std::string& dirname);
+ Result_t ResolveRID(const byte_t* uuid, FrameBuffer& FrameBuf) const;
+ };
+
//
class DCSubtitleParser
{
diff --git a/src/AS_DCP_DCData.cpp b/src/AS_DCP_DCData.cpp
index faa02a0..a1bb043 100644
--- a/src/AS_DCP_DCData.cpp
+++ b/src/AS_DCP_DCData.cpp
@@ -414,7 +414,7 @@ ASDCP::DCData::h__Writer::SetSourceStream(DCDataDescriptor const& DDesc,
{
ui32_t TCFrameRate = m_DDesc.EditRate.Numerator;
- result = WriteASDCPHeader(packageLabel, UL(m_Dict->ul(MDD_DCDataWrapping)),
+ result = WriteASDCPHeader(packageLabel, UL(m_Dict->ul(MDD_DCDataWrappingFrame)),
defLabel, UL(m_EssenceUL), UL(m_Dict->ul(MDD_DataDataDef)),
m_DDesc.EditRate, TCFrameRate);
}
diff --git a/src/AS_DCP_JP2K.cpp b/src/AS_DCP_JP2K.cpp
index b2f2eaf..1b3bc54 100755
--- a/src/AS_DCP_JP2K.cpp
+++ b/src/AS_DCP_JP2K.cpp
@@ -208,39 +208,26 @@ static const byte_t s_PixelLayoutXYZ[PixelLayoutSize] = { 0xd8, 0x0c, 0xd9, 0x0c
ASDCP::Result_t
ASDCP::JP2K_PDesc_to_MD(const JP2K::PictureDescriptor& PDesc,
const ASDCP::Dictionary& dict,
- ASDCP::MXF::RGBAEssenceDescriptor *EssenceDescriptor,
- ASDCP::MXF::JPEG2000PictureSubDescriptor *EssenceSubDescriptor)
-{
- if ( EssenceDescriptor == 0 || EssenceSubDescriptor == 0 )
- return RESULT_PTR;
-
- EssenceDescriptor->ContainerDuration = PDesc.ContainerDuration;
- EssenceDescriptor->SampleRate = PDesc.EditRate;
- EssenceDescriptor->FrameLayout = 0;
- EssenceDescriptor->StoredWidth = PDesc.StoredWidth;
- EssenceDescriptor->StoredHeight = PDesc.StoredHeight;
- EssenceDescriptor->AspectRatio = PDesc.AspectRatio;
-
- if ( PDesc.StoredWidth < 2049 )
- {
- EssenceDescriptor->PictureEssenceCoding.Set(dict.ul(MDD_JP2KEssenceCompression_2K));
- EssenceSubDescriptor->Rsize = 3;
- }
- else
- {
- EssenceDescriptor->PictureEssenceCoding.Set(dict.ul(MDD_JP2KEssenceCompression_4K));
- EssenceSubDescriptor->Rsize = 4;
- }
-
- EssenceSubDescriptor->Xsize = PDesc.Xsize;
- EssenceSubDescriptor->Ysize = PDesc.Ysize;
- EssenceSubDescriptor->XOsize = PDesc.XOsize;
- EssenceSubDescriptor->YOsize = PDesc.YOsize;
- EssenceSubDescriptor->XTsize = PDesc.XTsize;
- EssenceSubDescriptor->YTsize = PDesc.YTsize;
- EssenceSubDescriptor->XTOsize = PDesc.XTOsize;
- EssenceSubDescriptor->YTOsize = PDesc.YTOsize;
- EssenceSubDescriptor->Csize = PDesc.Csize;
+ ASDCP::MXF::GenericPictureEssenceDescriptor& EssenceDescriptor,
+ ASDCP::MXF::JPEG2000PictureSubDescriptor& EssenceSubDescriptor)
+{
+ EssenceDescriptor.ContainerDuration = PDesc.ContainerDuration;
+ EssenceDescriptor.SampleRate = PDesc.EditRate;
+ EssenceDescriptor.FrameLayout = 0;
+ EssenceDescriptor.StoredWidth = PDesc.StoredWidth;
+ EssenceDescriptor.StoredHeight = PDesc.StoredHeight;
+ EssenceDescriptor.AspectRatio = PDesc.AspectRatio;
+
+ EssenceSubDescriptor.Rsize = PDesc.Rsize;
+ EssenceSubDescriptor.Xsize = PDesc.Xsize;
+ EssenceSubDescriptor.Ysize = PDesc.Ysize;
+ EssenceSubDescriptor.XOsize = PDesc.XOsize;
+ EssenceSubDescriptor.YOsize = PDesc.YOsize;
+ EssenceSubDescriptor.XTsize = PDesc.XTsize;
+ EssenceSubDescriptor.YTsize = PDesc.YTsize;
+ EssenceSubDescriptor.XTOsize = PDesc.XTOsize;
+ EssenceSubDescriptor.YTOsize = PDesc.YTOsize;
+ EssenceSubDescriptor.Csize = PDesc.Csize;
const ui32_t tmp_buffer_len = 1024;
byte_t tmp_buffer[tmp_buffer_len];
@@ -249,142 +236,24 @@ ASDCP::JP2K_PDesc_to_MD(const JP2K::PictureDescriptor& PDesc,
*(ui32_t*)(tmp_buffer+4) = KM_i32_BE(sizeof(ASDCP::JP2K::ImageComponent_t));
memcpy(tmp_buffer + 8, &PDesc.ImageComponents, sizeof(ASDCP::JP2K::ImageComponent_t) * MaxComponents);
- const ui32_t pcomp_size = (sizeof(int) * 2) + (sizeof(ASDCP::JP2K::ImageComponent_t) * MaxComponents);
- memcpy(EssenceSubDescriptor->PictureComponentSizing.get().Data(), tmp_buffer, pcomp_size);
- EssenceSubDescriptor->PictureComponentSizing.get().Length(pcomp_size);
-
- ui32_t precinct_set_size = 0, i;
- for ( i = 0; PDesc.CodingStyleDefault.SPcod.PrecinctSize[i] != 0 && i < MaxPrecincts; i++ )
- precinct_set_size++;
-
- ui32_t csd_size = sizeof(CodingStyleDefault_t) - MaxPrecincts + precinct_set_size;
- memcpy(EssenceSubDescriptor->CodingStyleDefault.get().Data(), &PDesc.CodingStyleDefault, csd_size);
- EssenceSubDescriptor->CodingStyleDefault.get().Length(csd_size);
-
- ui32_t qdflt_size = PDesc.QuantizationDefault.SPqcdLength + 1;
- memcpy(EssenceSubDescriptor->QuantizationDefault.get().Data(), &PDesc.QuantizationDefault, qdflt_size);
- EssenceSubDescriptor->QuantizationDefault.get().Length(qdflt_size);
-
- return RESULT_OK;
-}
-
-
-//
-ASDCP::Result_t
-ASDCP::MD_to_JP2K_PDesc(const ASDCP::MXF::RGBAEssenceDescriptor& EssenceDescriptor,
- const ASDCP::MXF::JPEG2000PictureSubDescriptor& EssenceSubDescriptor,
- const ASDCP::Rational& EditRate, const ASDCP::Rational& SampleRate,
- ASDCP::JP2K::PictureDescriptor& PDesc)
-{
- memset(&PDesc, 0, sizeof(PDesc));
-
- PDesc.EditRate = EditRate;
- PDesc.SampleRate = SampleRate;
- assert(EssenceDescriptor.ContainerDuration.const_get() <= 0xFFFFFFFFL);
- PDesc.ContainerDuration = static_cast<ui32_t>(EssenceDescriptor.ContainerDuration.const_get());
- PDesc.StoredWidth = EssenceDescriptor.StoredWidth;
- PDesc.StoredHeight = EssenceDescriptor.StoredHeight;
- PDesc.AspectRatio = EssenceDescriptor.AspectRatio;
-
- PDesc.Rsize = EssenceSubDescriptor.Rsize;
- PDesc.Xsize = EssenceSubDescriptor.Xsize;
- PDesc.Ysize = EssenceSubDescriptor.Ysize;
- PDesc.XOsize = EssenceSubDescriptor.XOsize;
- PDesc.YOsize = EssenceSubDescriptor.YOsize;
- PDesc.XTsize = EssenceSubDescriptor.XTsize;
- PDesc.YTsize = EssenceSubDescriptor.YTsize;
- PDesc.XTOsize = EssenceSubDescriptor.XTOsize;
- PDesc.YTOsize = EssenceSubDescriptor.YTOsize;
- PDesc.Csize = EssenceSubDescriptor.Csize;
-
- // PictureComponentSizing
- ui32_t tmp_size = EssenceSubDescriptor.PictureComponentSizing.const_get().Length();
+ const ui32_t pcomp_size = (sizeof(ui32_t) * 2) + (sizeof(ASDCP::JP2K::ImageComponent_t) * MaxComponents);
+ memcpy(EssenceSubDescriptor.PictureComponentSizing.get().Data(), tmp_buffer, pcomp_size);
+ EssenceSubDescriptor.PictureComponentSizing.get().Length(pcomp_size);
+ EssenceSubDescriptor.PictureComponentSizing.set_has_value();
- if ( tmp_size == 17 ) // ( 2 * sizeof(ui32_t) ) + 3 components * 3 byte each
- {
- memcpy(&PDesc.ImageComponents, EssenceSubDescriptor.PictureComponentSizing.const_get().RoData() + 8, tmp_size - 8);
- }
- else
- {
- DefaultLogSink().Error("Unexpected PictureComponentSizing size: %u, should be 17\n", tmp_size);
- }
-
- // CodingStyleDefault
- memset(&PDesc.CodingStyleDefault, 0, sizeof(CodingStyleDefault_t));
- memcpy(&PDesc.CodingStyleDefault,
- EssenceSubDescriptor.CodingStyleDefault.const_get().RoData(),
- EssenceSubDescriptor.CodingStyleDefault.const_get().Length());
-
- // QuantizationDefault
- memset(&PDesc.QuantizationDefault, 0, sizeof(QuantizationDefault_t));
- memcpy(&PDesc.QuantizationDefault,
- EssenceSubDescriptor.QuantizationDefault.const_get().RoData(),
- EssenceSubDescriptor.QuantizationDefault.const_get().Length());
-
- PDesc.QuantizationDefault.SPqcdLength = EssenceSubDescriptor.QuantizationDefault.const_get().Length() - 1;
- return RESULT_OK;
-}
-
-//
-ASDCP::Result_t
-ASDCP::JP2K_PDesc_to_MD(const JP2K::PictureDescriptor& PDesc,
- const ASDCP::Dictionary& dict,
- ASDCP::MXF::CDCIEssenceDescriptor *EssenceDescriptor,
- ASDCP::MXF::JPEG2000PictureSubDescriptor *EssenceSubDescriptor)
-{
- if ( EssenceDescriptor == 0 || EssenceSubDescriptor == 0 )
- return RESULT_PTR;
-
- EssenceDescriptor->ContainerDuration = PDesc.ContainerDuration;
- EssenceDescriptor->SampleRate = PDesc.EditRate;
- EssenceDescriptor->FrameLayout = 0;
- EssenceDescriptor->StoredWidth = PDesc.StoredWidth;
- EssenceDescriptor->StoredHeight = PDesc.StoredHeight;
- EssenceDescriptor->AspectRatio = PDesc.AspectRatio;
-
- if ( PDesc.StoredWidth < 2049 )
- {
- EssenceDescriptor->PictureEssenceCoding.Set(dict.ul(MDD_JP2KEssenceCompression_2K));
- EssenceSubDescriptor->Rsize = 3;
- }
- else
- {
- EssenceDescriptor->PictureEssenceCoding.Set(dict.ul(MDD_JP2KEssenceCompression_4K));
- EssenceSubDescriptor->Rsize = 4;
- }
-
- EssenceSubDescriptor->Xsize = PDesc.Xsize;
- EssenceSubDescriptor->Ysize = PDesc.Ysize;
- EssenceSubDescriptor->XOsize = PDesc.XOsize;
- EssenceSubDescriptor->YOsize = PDesc.YOsize;
- EssenceSubDescriptor->XTsize = PDesc.XTsize;
- EssenceSubDescriptor->YTsize = PDesc.YTsize;
- EssenceSubDescriptor->XTOsize = PDesc.XTOsize;
- EssenceSubDescriptor->YTOsize = PDesc.YTOsize;
- EssenceSubDescriptor->Csize = PDesc.Csize;
-
- const ui32_t tmp_buffer_len = 1024;
- byte_t tmp_buffer[tmp_buffer_len];
-
- *(ui32_t*)tmp_buffer = KM_i32_BE(MaxComponents); // three components
- *(ui32_t*)(tmp_buffer+4) = KM_i32_BE(sizeof(ASDCP::JP2K::ImageComponent_t));
- memcpy(tmp_buffer + 8, &PDesc.ImageComponents, sizeof(ASDCP::JP2K::ImageComponent_t) * MaxComponents);
-
- const ui32_t pcomp_size = (sizeof(int) * 2) + (sizeof(ASDCP::JP2K::ImageComponent_t) * MaxComponents);
- memcpy(EssenceSubDescriptor->PictureComponentSizing.get().Data(), tmp_buffer, pcomp_size);
- EssenceSubDescriptor->PictureComponentSizing.get().Length(pcomp_size);
-
- ui32_t precinct_set_size = 0, i;
- for ( i = 0; PDesc.CodingStyleDefault.SPcod.PrecinctSize[i] != 0 && i < MaxPrecincts; i++ )
+ ui32_t precinct_set_size = 0;
+ for ( ui32_t i = 0; PDesc.CodingStyleDefault.SPcod.PrecinctSize[i] != 0 && i < MaxPrecincts; ++i )
precinct_set_size++;
ui32_t csd_size = sizeof(CodingStyleDefault_t) - MaxPrecincts + precinct_set_size;
- memcpy(EssenceSubDescriptor->CodingStyleDefault.get().Data(), &PDesc.CodingStyleDefault, csd_size);
- EssenceSubDescriptor->CodingStyleDefault.get().Length(csd_size);
+ memcpy(EssenceSubDescriptor.CodingStyleDefault.get().Data(), &PDesc.CodingStyleDefault, csd_size);
+ EssenceSubDescriptor.CodingStyleDefault.get().Length(csd_size);
+ EssenceSubDescriptor.CodingStyleDefault.set_has_value();
ui32_t qdflt_size = PDesc.QuantizationDefault.SPqcdLength + 1;
- memcpy(EssenceSubDescriptor->QuantizationDefault.get().Data(), &PDesc.QuantizationDefault, qdflt_size);
- EssenceSubDescriptor->QuantizationDefault.get().Length(qdflt_size);
+ memcpy(EssenceSubDescriptor.QuantizationDefault.get().Data(), &PDesc.QuantizationDefault, qdflt_size);
+ EssenceSubDescriptor.QuantizationDefault.get().Length(qdflt_size);
+ EssenceSubDescriptor.QuantizationDefault.set_has_value();
return RESULT_OK;
}
@@ -392,7 +261,7 @@ ASDCP::JP2K_PDesc_to_MD(const JP2K::PictureDescriptor& PDesc,
//
ASDCP::Result_t
-ASDCP::MD_to_JP2K_PDesc(const ASDCP::MXF::CDCIEssenceDescriptor& EssenceDescriptor,
+ASDCP::MD_to_JP2K_PDesc(const ASDCP::MXF::GenericPictureEssenceDescriptor& EssenceDescriptor,
const ASDCP::MXF::JPEG2000PictureSubDescriptor& EssenceSubDescriptor,
const ASDCP::Rational& EditRate, const ASDCP::Rational& SampleRate,
ASDCP::JP2K::PictureDescriptor& PDesc)
@@ -446,22 +315,6 @@ ASDCP::MD_to_JP2K_PDesc(const ASDCP::MXF::CDCIEssenceDescriptor& EssenceDescrip
return RESULT_OK;
}
-// Compares the actual floating point value of the rates.
-// This allows, for example, {300000,1001} and {2997,100) to be considered equivalent.
-// to 29.97.
-bool
-epsilon_compare(const ASDCP::Rational& left, const ASDCP::Rational& right, double epsilon = 0.001)
-{
- bool result = false;
- double difference = left.Quotient() - right.Quotient();
-
- if (fabs(difference) < epsilon)
- result = true;
-
- return result;
-}
-// end DOLBY
-
//------------------------------------------------------------------------------------------
//
@@ -1134,12 +987,25 @@ lh__Writer::SetSourceStream(const PictureDescriptor& PDesc, const std::string& l
m_PDesc = PDesc;
assert(m_Dict);
+ assert(m_EssenceDescriptor);
+ assert(m_EssenceSubDescriptor);
Result_t result = JP2K_PDesc_to_MD(m_PDesc, *m_Dict,
- (ASDCP::MXF::RGBAEssenceDescriptor*)m_EssenceDescriptor,
- m_EssenceSubDescriptor);
+ *static_cast<ASDCP::MXF::GenericPictureEssenceDescriptor*>(m_EssenceDescriptor),
+ *m_EssenceSubDescriptor);
if ( ASDCP_SUCCESS(result) )
{
+ if ( PDesc.StoredWidth < 2049 )
+ {
+ static_cast<ASDCP::MXF::RGBAEssenceDescriptor*>(m_EssenceDescriptor)->PictureEssenceCoding.Set(m_Dict->ul(MDD_JP2KEssenceCompression_2K));
+ m_EssenceSubDescriptor->Rsize = 3;
+ }
+ else
+ {
+ static_cast<ASDCP::MXF::RGBAEssenceDescriptor*>(m_EssenceDescriptor)->PictureEssenceCoding.Set(m_Dict->ul(MDD_JP2KEssenceCompression_4K));
+ m_EssenceSubDescriptor->Rsize = 4;
+ }
+
memcpy(m_EssenceUL, m_Dict->ul(MDD_JPEG2000Essence), SMPTE_UL_LENGTH);
m_EssenceUL[SMPTE_UL_LENGTH-1] = 1; // first (and only) essence container
result = m_State.Goto_READY();
@@ -1147,7 +1013,7 @@ lh__Writer::SetSourceStream(const PictureDescriptor& PDesc, const std::string& l
if ( ASDCP_SUCCESS(result) )
{
- result = WriteASDCPHeader(label, UL(m_Dict->ul(MDD_JPEG_2000Wrapping)),
+ result = WriteASDCPHeader(label, UL(m_Dict->ul(MDD_JPEG_2000WrappingFrame)),
PICT_DEF_LABEL, UL(m_EssenceUL), UL(m_Dict->ul(MDD_PictureDataDef)),
LocalEditRate, derive_timecode_rate_from_edit_rate(m_PDesc.EditRate));
}
diff --git a/src/AS_DCP_MPEG2.cpp b/src/AS_DCP_MPEG2.cpp
index d7cc935..21991bf 100755
--- a/src/AS_DCP_MPEG2.cpp
+++ b/src/AS_DCP_MPEG2.cpp
@@ -568,7 +568,7 @@ ASDCP::MPEG2::MXFWriter::h__Writer::SetSourceStream(const VideoDescriptor& VDesc
if ( ASDCP_SUCCESS(result) )
{
- result = WriteASDCPHeader(MPEG_PACKAGE_LABEL, UL(m_Dict->ul(MDD_MPEG2_VESWrapping)),
+ result = WriteASDCPHeader(MPEG_PACKAGE_LABEL, UL(m_Dict->ul(MDD_MPEG2_VESWrappingFrame)),
PICT_DEF_LABEL, UL(m_EssenceUL), UL(m_Dict->ul(MDD_PictureDataDef)),
m_VDesc.EditRate, derive_timecode_rate_from_edit_rate(m_VDesc.EditRate));
}
diff --git a/src/AS_DCP_PCM.cpp b/src/AS_DCP_PCM.cpp
index 8cff9cf..8011a55 100755
--- a/src/AS_DCP_PCM.cpp
+++ b/src/AS_DCP_PCM.cpp
@@ -577,7 +577,7 @@ ASDCP::PCM::MXFWriter::h__Writer::SetSourceStream(const AudioDescriptor& ADesc)
if ( ASDCP_SUCCESS(result) )
{
- result = WriteASDCPHeader(PCM_PACKAGE_LABEL, UL(m_Dict->ul(MDD_WAVWrapping)),
+ result = WriteASDCPHeader(PCM_PACKAGE_LABEL, UL(m_Dict->ul(MDD_WAVWrappingFrame)),
SOUND_DEF_LABEL, UL(m_EssenceUL), UL(m_Dict->ul(MDD_SoundDataDef)),
m_ADesc.EditRate, derive_timecode_rate_from_edit_rate(m_ADesc.EditRate),
calc_CBR_frame_size(m_Info, m_ADesc));
diff --git a/src/AS_DCP_TimedText.cpp b/src/AS_DCP_TimedText.cpp
index ac95e24..e5425b4 100644
--- a/src/AS_DCP_TimedText.cpp
+++ b/src/AS_DCP_TimedText.cpp
@@ -593,7 +593,7 @@ ASDCP::TimedText::MXFWriter::h__Writer::SetSourceStream(ASDCP::TimedText::TimedT
AddDMSegment(m_TDesc.EditRate, m_TDesc.EditRate, derive_timecode_rate_from_edit_rate(m_TDesc.EditRate), TIMED_TEXT_DEF_LABEL,
UL(m_Dict->ul(MDD_DataDataDef)), TIMED_TEXT_PACKAGE_LABEL);
- AddEssenceDescriptor(UL(m_Dict->ul(MDD_TimedTextWrapping)));
+ AddEssenceDescriptor(UL(m_Dict->ul(MDD_TimedTextWrappingClip)));
result = m_HeaderPart.WriteToFile(m_File, m_HeaderSize);
diff --git a/src/AS_DCP_internal.h b/src/AS_DCP_internal.h
index 8b05dc7..675f96d 100755
--- a/src/AS_DCP_internal.h
+++ b/src/AS_DCP_internal.h
@@ -134,25 +134,15 @@ namespace ASDCP
Result_t EncryptFrameBuffer(const ASDCP::FrameBuffer&, ASDCP::FrameBuffer&, AESEncContext*);
Result_t DecryptFrameBuffer(const ASDCP::FrameBuffer&, ASDCP::FrameBuffer&, AESDecContext*);
- Result_t MD_to_JP2K_PDesc(const ASDCP::MXF::RGBAEssenceDescriptor& EssenceDescriptor,
+ Result_t MD_to_JP2K_PDesc(const ASDCP::MXF::GenericPictureEssenceDescriptor& EssenceDescriptor,
const ASDCP::MXF::JPEG2000PictureSubDescriptor& EssenceSubDescriptor,
const ASDCP::Rational& EditRate, const ASDCP::Rational& SampleRate,
ASDCP::JP2K::PictureDescriptor& PDesc);
Result_t JP2K_PDesc_to_MD(const JP2K::PictureDescriptor& PDesc,
const ASDCP::Dictionary& dict,
- ASDCP::MXF::RGBAEssenceDescriptor *EssenceDescriptor,
- ASDCP::MXF::JPEG2000PictureSubDescriptor *EssenceSubDescriptor);
-
- Result_t MD_to_JP2K_PDesc(const ASDCP::MXF::CDCIEssenceDescriptor& EssenceDescriptor,
- const ASDCP::MXF::JPEG2000PictureSubDescriptor& EssenceSubDescriptor,
- const ASDCP::Rational& EditRate, const ASDCP::Rational& SampleRate,
- ASDCP::JP2K::PictureDescriptor& PDesc);
-
- Result_t JP2K_PDesc_to_MD(const JP2K::PictureDescriptor& PDesc,
- const ASDCP::Dictionary& dict,
- ASDCP::MXF::CDCIEssenceDescriptor *EssenceDescriptor,
- ASDCP::MXF::JPEG2000PictureSubDescriptor *EssenceSubDescriptor);
+ ASDCP::MXF::GenericPictureEssenceDescriptor& EssenceDescriptor,
+ ASDCP::MXF::JPEG2000PictureSubDescriptor& EssenceSubDescriptor);
Result_t PCM_ADesc_to_MD(PCM::AudioDescriptor& ADesc, ASDCP::MXF::WaveAudioDescriptor* ADescObj);
Result_t MD_to_PCM_ADesc(ASDCP::MXF::WaveAudioDescriptor* ADescObj, PCM::AudioDescriptor& ADesc);
diff --git a/src/MDD.cpp b/src/MDD.cpp
index fa88016..a15956c 100644
--- a/src/MDD.cpp
+++ b/src/MDD.cpp
@@ -64,13 +64,13 @@ static const ASDCP::MDDEntry s_MDD_Table[] = {
{0}, false, "DescriptiveMetaDataDef" },
{ { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01, // 9
0x0d, 0x01, 0x03, 0x01, 0x02, 0x06, 0x01, 0x00 },
- {0}, false, "WAVWrapping" },
+ {0}, false, "WAVWrappingFrame" },
{ { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x02, // 10
0x0d, 0x01, 0x03, 0x01, 0x02, 0x04, 0x60, 0x00 },
- {0}, false, "MPEG2_VESWrapping" },
+ {0}, false, "MPEG2_VESWrappingFrame" },
{ { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x07, // 11
0x0d, 0x01, 0x03, 0x01, 0x02, 0x0c, 0x01, 0x00 },
- {0}, false, "JPEG_2000Wrapping" },
+ {0}, false, "JPEG_2000WrappingFrame" },
{ { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x02, 0x01, 0x01, // 12
0x0d, 0x01, 0x03, 0x01, 0x15, 0x01, 0x08, 0x00 },
{0}, false, "JPEG2000Essence" },
@@ -802,7 +802,7 @@ static const ASDCP::MDDEntry s_MDD_Table[] = {
{0}, false, "CryptographicContext_CryptographicKeyID" },
{ { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x0a, // 255
0x0d, 0x01, 0x03, 0x01, 0x02, 0x13, 0x01, 0x01 },
- {0}, false, "TimedTextWrapping" },
+ {0}, false, "TimedTextWrappingClip" },
{ { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x02, 0x01, 0x01, // 256
0x0d, 0x01, 0x03, 0x01, 0x17, 0x01, 0x0b, 0x01 },
{0}, false, "TimedTextEssence" },
@@ -842,7 +842,7 @@ static const ASDCP::MDDEntry s_MDD_Table[] = {
{ { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02, // 268
0x01, 0x07, 0x01, 0x05, 0x00, 0x00, 0x00, 0x00 },
{0x61, 0x02}, false, "DMSegment_TrackIDList" },
- { { 0x06, 0x0e, 0x2b, 0x34, 0x02, 0x53, 0x01, 0x0c, // 269
+ { { 0x06, 0x0e, 0x2b, 0x34, 0x02, 0x53, 0x01, 0x01, // 269
0x0d, 0x01, 0x01, 0x01, 0x01, 0x01, 0x63, 0x00 },
{0}, false, "StereoscopicPictureSubDescriptor" },
{ { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x07, // 270
@@ -919,7 +919,7 @@ static const ASDCP::MDDEntry s_MDD_Table[] = {
{0}, false, "SoundfieldGroupLabelSubDescriptor_GroupOfSoundfieldGroupsLinkID" },
{ { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x05, // 294
0x0e, 0x09, 0x06, 0x05, 0x00, 0x00, 0x00, 0x00 },
- {0}, false, "DCDataWrapping" },
+ {0}, false, "DCDataWrappingFrame" },
{ { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x02, 0x01, 0x05, // 295
0x0e, 0x09, 0x06, 0x01, 0x00, 0x00, 0x00, 0x00 },
{0}, false, "DCDataEssence" },
@@ -1091,7 +1091,7 @@ static const ASDCP::MDDEntry s_MDD_Table[] = {
{ { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02, // 351
0x04, 0x01, 0x02, 0x01, 0x01, 0x03, 0x01, 0x00 },
{0}, false, "GenericPictureEssenceDescriptor_CodingEquations" },
- { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02, // 352
+ { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x09, // 352
0x04, 0x01, 0x02, 0x01, 0x01, 0x06, 0x01, 0x00 },
{0}, false, "GenericPictureEssenceDescriptor_ColorPrimaries" },
{ { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x0d, // 353
@@ -1124,16 +1124,16 @@ static const ASDCP::MDDEntry s_MDD_Table[] = {
{ { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x0e, // 362
0x04, 0x01, 0x03, 0x02, 0x0b, 0x00, 0x00, 0x00 },
{0}, false, "GenericPictureEssenceDescriptor_AlternativeCenterCuts" },
- { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x0e, // 363
+ { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x01, // 363
0x04, 0x01, 0x05, 0x01, 0x13, 0x00, 0x00, 0x00 },
{0x32, 0x05}, true, "GenericPictureEssenceDescriptor_ActiveHeight" },
- { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x0e, // 364
+ { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x01, // 364
0x04, 0x01, 0x05, 0x01, 0x14, 0x00, 0x00, 0x00 },
{0x32, 0x04}, true, "GenericPictureEssenceDescriptor_ActiveWidth" },
- { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x0e, // 365
+ { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x01, // 365
0x04, 0x01, 0x05, 0x01, 0x15, 0x00, 0x00, 0x00 },
{0x32, 0x06}, true, "GenericPictureEssenceDescriptor_ActiveXOffset" },
- { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x0e, // 366
+ { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x01, // 366
0x04, 0x01, 0x05, 0x01, 0x16, 0x00, 0x00, 0x00 },
{0x32, 0x07}, true, "GenericPictureEssenceDescriptor_ActiveYOffset" },
{ { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x0e, // 367
@@ -1145,6 +1145,10 @@ static const ASDCP::MDDEntry s_MDD_Table[] = {
{ { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x0d, // 369
0x04, 0x01, 0x01, 0x01, 0x00, 0x04, 0x02, 0x00 },
{0}, false, "AlternativeCenterCuts_14x9" },
+ { { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01, // 370
+ 0x0d, 0x01, 0x03, 0x01, 0x02, 0x06, 0x02, 0x00 },
+ {0}, false, "WAVWrappingClip" },
+
{ {0}, {0}, false, 0 }
};
diff --git a/src/MDD.h b/src/MDD.h
index bb8db7a..e622c6a 100755
--- a/src/MDD.h
+++ b/src/MDD.h
@@ -44,9 +44,9 @@ namespace ASDCP {
MDD_SoundDataDef, // 6
MDD_TimecodeDataDef, // 7
MDD_DescriptiveMetaDataDef, // 8
- MDD_WAVWrapping, // 9
- MDD_MPEG2_VESWrapping, // 10
- MDD_JPEG_2000Wrapping, // 11
+ MDD_WAVWrappingFrame, // 9
+ MDD_MPEG2_VESWrappingFrame, // 10
+ MDD_JPEG_2000WrappingFrame, // 11
MDD_JPEG2000Essence, // 12
MDD_MPEG2Essence, // 13
MDD_MXFInterop_CryptEssence, // 14
@@ -290,7 +290,7 @@ namespace ASDCP {
MDD_CryptographicContext_CipherAlgorithm, // 252
MDD_CryptographicContext_MICAlgorithm, // 253
MDD_CryptographicContext_CryptographicKeyID, // 254
- MDD_TimedTextWrapping, // 255
+ MDD_TimedTextWrappingClip, // 255
MDD_TimedTextEssence, // 256
MDD_TimedTextDescriptor, // 257
MDD_TimedTextDescriptor_ResourceID, // 258
@@ -329,7 +329,7 @@ namespace ASDCP {
MDD_MCALabelSubDescriptor_RFC5646SpokenLanguage, // 291
MDD_AudioChannelLabelSubDescriptor_SoundfieldGroupLinkID, // 292
MDD_SoundfieldGroupLabelSubDescriptor_GroupOfSoundfieldGroupsLinkID, // 293
- MDD_DCDataWrapping, // 294
+ MDD_DCDataWrappingFrame, // 294
MDD_DCDataEssence, // 295
MDD_DCDataDescriptor, // 296
MDD_DolbyAtmosSubDescriptor, // 297
@@ -405,6 +405,7 @@ namespace ASDCP {
MDD_TimedTextDescriptor_RFC5646LanguageTagList, // 367
MDD_AlternativeCenterCuts_4x3, // 368
MDD_AlternativeCenterCuts_14x9, // 369
+ MDD_WAVWrappingClip, // 370
MDD_Max
}; // enum MDD_t
diff --git a/src/MXF.cpp b/src/MXF.cpp
index 15a9ba0..02bf1e9 100755
--- a/src/MXF.cpp
+++ b/src/MXF.cpp
@@ -1099,17 +1099,17 @@ ASDCP::MXF::OPAtomIndexFooter::WriteToFile(Kumu::FileWriter& Writer, ui64_t dura
std::list<InterchangeObject*>::iterator pl_i = m_PacketList->m_List.begin();
for ( ; pl_i != m_PacketList->m_List.end() && ASDCP_SUCCESS(result); pl_i++ )
{
- if ( (*pl_i)->IsA(OBJ_TYPE_ARGS(IndexTableSegment)) )
+ IndexTableSegment *segment = dynamic_cast<IndexTableSegment*>(*pl_i);
+
+ if ( segment != 0 )
{
iseg_count++;
- IndexTableSegment* Segment = (IndexTableSegment*)(*pl_i);
-
if ( m_BytesPerEditUnit != 0 )
{
if ( iseg_count != 1 )
return RESULT_STATE;
- Segment->IndexDuration = duration;
+ segment->IndexDuration = duration;
}
}
@@ -1186,28 +1186,29 @@ ASDCP::MXF::OPAtomIndexFooter::Lookup(ui32_t frame_num, IndexTableSegment::Index
std::list<InterchangeObject*>::iterator li;
for ( li = m_PacketList->m_List.begin(); li != m_PacketList->m_List.end(); li++ )
{
- if ( (*li)->IsA(OBJ_TYPE_ARGS(IndexTableSegment)) )
+ IndexTableSegment *segment = dynamic_cast<IndexTableSegment*>(*li);
+
+ if ( segment != 0 )
{
- IndexTableSegment* Segment = (IndexTableSegment*)(*li);
- ui64_t start_pos = Segment->IndexStartPosition;
+ ui64_t start_pos = segment->IndexStartPosition;
- if ( Segment->EditUnitByteCount > 0 )
+ if ( segment->EditUnitByteCount > 0 )
{
if ( m_PacketList->m_List.size() > 1 )
DefaultLogSink().Error("Unexpected multiple IndexTableSegment in CBR file\n");
- if ( ! Segment->IndexEntryArray.empty() )
+ if ( ! segment->IndexEntryArray.empty() )
DefaultLogSink().Error("Unexpected IndexEntryArray contents in CBR file\n");
- Entry.StreamOffset = (ui64_t)frame_num * Segment->EditUnitByteCount;
+ Entry.StreamOffset = (ui64_t)frame_num * segment->EditUnitByteCount;
return RESULT_OK;
}
else if ( (ui64_t)frame_num >= start_pos
- && (ui64_t)frame_num < (start_pos + Segment->IndexDuration) )
+ && (ui64_t)frame_num < (start_pos + segment->IndexDuration) )
{
ui64_t tmp = frame_num - start_pos;
assert(tmp <= 0xFFFFFFFFL);
- Entry = Segment->IndexEntryArray[(ui32_t) tmp];
+ Entry = segment->IndexEntryArray[(ui32_t) tmp];
return RESULT_OK;
}
}
@@ -1375,7 +1376,7 @@ ASDCP::MXF::InterchangeObject::Dump(FILE* stream)
bool
ASDCP::MXF::InterchangeObject::IsA(const byte_t* label)
{
- if ( m_KLLength == 0 )
+ if ( m_KLLength == 0 || m_KeyStart == 0 )
return false;
return ( memcmp(label, m_KeyStart, SMPTE_UL_LENGTH) == 0 );
diff --git a/src/Makefile.am b/src/Makefile.am
index 0e921ad..c1bcf00 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -128,6 +128,8 @@ libas02_la_SOURCES = \
AS_02_internal.h \
h__02_Reader.cpp \
h__02_Writer.cpp \
+ ST2052_TextParser.cpp \
+ AS_02_TimedText.cpp \
AS_02_JP2K.cpp \
AS_02_PCM.cpp
diff --git a/src/TimedText_Parser.cpp b/src/TimedText_Parser.cpp
index a1f3de4..b7b58c5 100644
--- a/src/TimedText_Parser.cpp
+++ b/src/TimedText_Parser.cpp
@@ -1,5 +1,5 @@
/*
-Copyright (c) 2007-2009, John Hurst
+Copyright (c) 2007-2013, John Hurst
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -44,54 +44,61 @@ const char* c_dcst_namespace_name = "http://www.smpte-ra.org/schemas/428-7/2007/
//------------------------------------------------------------------------------------------
+ASDCP::TimedText::LocalFilenameResolver::LocalFilenameResolver() {}
-class LocalFilenameResolver : public ASDCP::TimedText::IResourceResolver
+//
+Result_t
+ASDCP::TimedText::LocalFilenameResolver::OpenRead(const std::string& dirname)
{
- std::string m_Dirname;
-
- LocalFilenameResolver();
- bool operator==(const LocalFilenameResolver&);
-
-public:
- LocalFilenameResolver(const std::string& dirname)
- {
- if ( PathIsDirectory(dirname) )
- {
- m_Dirname = dirname;
- return;
- }
-
- DefaultLogSink().Error("Path '%s' is not a directory, defaulting to '.'\n", dirname.c_str());
- m_Dirname = ".";
- }
+ if ( PathIsDirectory(dirname) )
+ {
+ m_Dirname = dirname;
+ return RESULT_OK;
+ }
- //
- Result_t ResolveRID(const byte_t* uuid, TimedText::FrameBuffer& FrameBuf) const
- {
- FileReader Reader;
- char buf[64];
- UUID RID(uuid);
- std::string filename = m_Dirname + "/" + RID.EncodeHex(buf, 64);
- DefaultLogSink().Debug("retrieving resource %s from file %s\n", buf, filename.c_str());
+ DefaultLogSink().Error("Path '%s' is not a directory, defaulting to '.'\n", dirname.c_str());
+ m_Dirname = ".";
+ return RESULT_FALSE;
+}
- Result_t result = Reader.OpenRead(filename.c_str());
+//
+Result_t
+ASDCP::TimedText::LocalFilenameResolver::ResolveRID(const byte_t* uuid, TimedText::FrameBuffer& FrameBuf) const
+{
+ Result_t result = RESULT_NOT_FOUND;
+ char buf[64];
+ UUID RID(uuid);
+ PathList_t found_list;
- if ( KM_SUCCESS(result) )
- {
- ui32_t read_count, read_size = Reader.Size();
+ FindInPath(PathMatchRegex(RID.EncodeHex(buf, 64)), m_Dirname, found_list);
- result = FrameBuf.Capacity(read_size);
+ if ( found_list.size() == 1 )
+ {
+ FileReader Reader;
+ DefaultLogSink().Debug("retrieving resource %s from file %s\n", buf, found_list.front().c_str());
- if ( KM_SUCCESS(result) )
- result = Reader.Read(FrameBuf.Data(), read_size, &read_count);
+ result = Reader.OpenRead(found_list.front().c_str());
- if ( KM_SUCCESS(result) )
- FrameBuf.Size(read_count);
- }
+ if ( KM_SUCCESS(result) )
+ {
+ ui32_t read_count, read_size = Reader.Size();
+ result = FrameBuf.Capacity(read_size);
+
+ if ( KM_SUCCESS(result) )
+ result = Reader.Read(FrameBuf.Data(), read_size, &read_count);
+
+ if ( KM_SUCCESS(result) )
+ FrameBuf.Size(read_count);
+ }
+ }
+ else if ( ! found_list.empty() )
+ {
+ DefaultLogSink().Error("More than one file in %s matches %s.\n", m_Dirname.c_str(), buf);
+ result = RESULT_RAW_FORMAT;
+ }
- return result;
- }
-};
+ return result;
+}
//------------------------------------------------------------------------------------------
@@ -121,8 +128,11 @@ public:
TimedText::IResourceResolver* GetDefaultResolver()
{
if ( m_DefaultResolver.empty() )
- m_DefaultResolver = new LocalFilenameResolver(PathDirname(m_Filename));
-
+ {
+ m_DefaultResolver = new LocalFilenameResolver();
+ m_DefaultResolver->OpenRead(PathDirname(m_Filename));
+ }
+
return m_DefaultResolver;
}
@@ -448,5 +458,5 @@ ASDCP::TimedText::DCSubtitleParser::ReadAncillaryResource(const byte_t* uuid, Fr
//
-// end AS_DCP_timedText.cpp
+// end AS_DCP_TimedTextParser.cpp
//
diff --git a/src/as-02-wrap.cpp b/src/as-02-wrap.cpp
index 57515c4..0a31a60 100755
--- a/src/as-02-wrap.cpp
+++ b/src/as-02-wrap.cpp
@@ -179,6 +179,7 @@ public:
ui32_t start_frame; // frame number to begin processing
ui32_t duration; // number of frames to be processed
bool j2c_pedantic; // passed to JP2K::SequenceParser::OpenRead
+ bool use_cdci_descriptor; //
Rational edit_rate; // edit rate of JP2K sequence
ui32_t fb_size; // size of picture frame buffer
byte_t key_value[KeyLen]; // value of given encryption key (when key_flag is true)
@@ -190,6 +191,10 @@ public:
Kumu::PathList_t filenames; // list of filenames to be processed
UL channel_assignment;
ASDCP::MXF::AS02_MCAConfigParser mca_config;
+ ui32_t cdci_depth;
+ ui32_t rgba_MaxRef;
+ ui32_t rgba_MinRef;
+ ui32_t mxf_header_size;
//new attributes for AS-02 support
AS_02::IndexStrategy_t index_strategy; //Shim parameter index_strategy_frame/clip
@@ -200,9 +205,10 @@ public:
error_flag(true), key_flag(false), key_id_flag(false), asset_id_flag(false),
encrypt_header_flag(true), write_hmac(true), verbose_flag(false), fb_dump_size(0),
no_write_flag(false), version_flag(false), help_flag(false), start_frame(0),
- duration(0xffffffff), j2c_pedantic(true), edit_rate(24,1), fb_size(FRAME_BUFFER_SIZE),
+ duration(0xffffffff), j2c_pedantic(true), use_cdci_descriptor(false), edit_rate(24,1), fb_size(FRAME_BUFFER_SIZE),
show_ul_values_flag(false), index_strategy(AS_02::IS_FOLLOW), partition_space(60),
- mca_config(g_dict)
+ mca_config(g_dict), cdci_depth(0), rgba_MaxRef(1024), rgba_MinRef(0), mxf_header_size(16384)
+
{
memset(key_value, 0, KeyLen);
memset(key_id_value, 0, UUIDlen);
@@ -367,8 +373,8 @@ public:
namespace ASDCP {
Result_t JP2K_PDesc_to_MD(const ASDCP::JP2K::PictureDescriptor& PDesc,
const ASDCP::Dictionary& dict,
- ASDCP::MXF::RGBAEssenceDescriptor *EssenceDescriptor,
- ASDCP::MXF::JPEG2000PictureSubDescriptor *EssenceSubDescriptor);
+ ASDCP::MXF::GenericPictureEssenceDescriptor& GenericPictureEssenceDescriptor,
+ ASDCP::MXF::JPEG2000PictureSubDescriptor& EssenceSubDescriptor);
Result_t PCM_ADesc_to_MD(ASDCP::PCM::AudioDescriptor& ADesc, ASDCP::MXF::WaveAudioDescriptor* ADescObj);
}
@@ -386,7 +392,7 @@ write_JP2K_file(CommandOptions& Options)
JP2K::SequenceParser Parser;
byte_t IV_buf[CBC_BLOCK_SIZE];
Kumu::FortunaRNG RNG;
- ASDCP::MXF::RGBAEssenceDescriptor *essence_descriptor = 0;
+ ASDCP::MXF::FileDescriptor *essence_descriptor = 0;
ASDCP::MXF::InterchangeObject_list_t essence_sub_descriptors;
// set up essence parser
@@ -407,17 +413,47 @@ write_JP2K_file(CommandOptions& Options)
JP2K::PictureDescriptorDump(PDesc);
}
- // TODO: optionally set up CDCIEssenceDescriptor
- essence_descriptor = new ASDCP::MXF::RGBAEssenceDescriptor(g_dict);
- essence_sub_descriptors.push_back(new ASDCP::MXF::JPEG2000PictureSubDescriptor(g_dict));
+ if ( Options.use_cdci_descriptor )
+ {
+ ASDCP::MXF::CDCIEssenceDescriptor* tmp_dscr = new ASDCP::MXF::CDCIEssenceDescriptor(g_dict);
+ essence_sub_descriptors.push_back(new ASDCP::MXF::JPEG2000PictureSubDescriptor(g_dict));
+
+ result = ASDCP::JP2K_PDesc_to_MD(PDesc, *g_dict,
+ *static_cast<ASDCP::MXF::GenericPictureEssenceDescriptor*>(tmp_dscr),
+ *static_cast<ASDCP::MXF::JPEG2000PictureSubDescriptor*>(essence_sub_descriptors.back()));
+
+ if ( ASDCP_SUCCESS(result) )
+ {
+ // TODO, select profile
+ tmp_dscr->PictureEssenceCoding = UL(g_dict->ul(MDD_JP2KEssenceCompression_BroadcastProfile_1));
+ tmp_dscr->ComponentDepth = Options.cdci_depth;
+
+ // more options here
- result = ASDCP::JP2K_PDesc_to_MD(PDesc, *g_dict, essence_descriptor,
- reinterpret_cast<ASDCP::MXF::JPEG2000PictureSubDescriptor*>(essence_sub_descriptors.back()));
+ essence_descriptor = static_cast<ASDCP::MXF::FileDescriptor*>(tmp_dscr);
+ }
+ }
+ else
+ { // use RGB
+ ASDCP::MXF::RGBAEssenceDescriptor* tmp_dscr = new ASDCP::MXF::RGBAEssenceDescriptor(g_dict);
+ essence_sub_descriptors.push_back(new ASDCP::MXF::JPEG2000PictureSubDescriptor(g_dict));
+
+ result = ASDCP::JP2K_PDesc_to_MD(PDesc, *g_dict,
+ *static_cast<ASDCP::MXF::GenericPictureEssenceDescriptor*>(tmp_dscr),
+ *static_cast<ASDCP::MXF::JPEG2000PictureSubDescriptor*>(essence_sub_descriptors.back()));
+
+ if ( ASDCP_SUCCESS(result) )
+ {
+ // TODO, select profile
+ tmp_dscr->PictureEssenceCoding = UL(g_dict->ul(MDD_JP2KEssenceCompression_BroadcastProfile_1));
+ tmp_dscr->ComponentMaxRef = Options.rgba_MaxRef;
+ tmp_dscr->ComponentMinRef = Options.rgba_MinRef;
- /// TODO: set with magic or some such thing
- essence_descriptor->PictureEssenceCoding = UL(g_dict->ul(MDD_JP2KEssenceCompression_BroadcastProfile_1));
- essence_descriptor->ComponentMaxRef = 4095;
- essence_descriptor->ComponentMinRef = 0;
+ // more options here
+
+ essence_descriptor = static_cast<ASDCP::MXF::FileDescriptor*>(tmp_dscr);
+ }
+ }
}
if ( ASDCP_SUCCESS(result) && ! Options.no_write_flag )
@@ -457,11 +493,8 @@ write_JP2K_file(CommandOptions& Options)
if ( ASDCP_SUCCESS(result) )
{
- result = Writer.OpenWrite(Options.out_file, Info,
- static_cast<ASDCP::MXF::FileDescriptor*>(essence_descriptor),
- essence_sub_descriptors,
- Options.edit_rate, 16384, Options.index_strategy, Options.partition_space);
- // TODO: make 16384 part of CommandOptions
+ result = Writer.OpenWrite(Options.out_file, Info, essence_descriptor, essence_sub_descriptors,
+ Options.edit_rate, Options.mxf_header_size, Options.index_strategy, Options.partition_space);
}
}
@@ -510,8 +543,8 @@ write_JP2K_file(CommandOptions& Options)
// PCM essence
-// Write one or more plaintext PCM audio streams to a plaintext ASDCP file
-// Write one or more plaintext PCM audio streams to a ciphertext ASDCP file
+// Write one or more plaintext PCM audio streams to a plaintext AS-02 file
+// Write one or more plaintext PCM audio streams to a ciphertext AS-02 file
//
Result_t
write_PCM_file(CommandOptions& Options)
@@ -659,6 +692,121 @@ write_PCM_file(CommandOptions& Options)
}
+//------------------------------------------------------------------------------------------
+// TimedText essence
+
+
+// Write one or more plaintext timed text streams to a plaintext AS-02 file
+// Write one or more plaintext timed text streams to a ciphertext AS-02 file
+//
+Result_t
+write_timed_text_file(CommandOptions& Options)
+{
+ AESEncContext* Context = 0;
+ HMACContext* HMAC = 0;
+ AS_02::TimedText::ST2052_TextParser Parser;
+ AS_02::TimedText::MXFWriter Writer;
+ TimedText::FrameBuffer FrameBuffer;
+ TimedText::TimedTextDescriptor TDesc;
+ byte_t IV_buf[CBC_BLOCK_SIZE];
+ Kumu::FortunaRNG RNG;
+
+ // set up essence parser
+ Result_t result = Parser.OpenRead(Options.filenames.front().c_str());
+
+ // set up MXF writer
+ if ( ASDCP_SUCCESS(result) )
+ {
+ Parser.FillTimedTextDescriptor(TDesc);
+ FrameBuffer.Capacity(Options.fb_size);
+
+ if ( Options.verbose_flag )
+ {
+ fputs("IMF Timed-Text Descriptor:\n", stderr);
+ TimedText::DescriptorDump(TDesc);
+ }
+ }
+
+ if ( ASDCP_SUCCESS(result) && ! Options.no_write_flag )
+ {
+ WriterInfo Info = s_MyInfo; // fill in your favorite identifiers here
+ if ( Options.asset_id_flag )
+ memcpy(Info.AssetUUID, Options.asset_id_value, UUIDlen);
+ else
+ Kumu::GenRandomUUID(Info.AssetUUID);
+
+ // configure encryption
+ if( Options.key_flag )
+ {
+ Kumu::GenRandomUUID(Info.ContextID);
+ Info.EncryptedEssence = true;
+
+ if ( Options.key_id_flag )
+ memcpy(Info.CryptographicKeyID, Options.key_id_value, UUIDlen);
+ else
+ RNG.FillRandom(Info.CryptographicKeyID, UUIDlen);
+
+ Context = new AESEncContext;
+ result = Context->InitKey(Options.key_value);
+
+ if ( ASDCP_SUCCESS(result) )
+ result = Context->SetIVec(RNG.FillRandom(IV_buf, CBC_BLOCK_SIZE));
+
+ if ( ASDCP_SUCCESS(result) && Options.write_hmac )
+ {
+ Info.UsesHMAC = true;
+ HMAC = new HMACContext;
+ result = HMAC->InitKey(Options.key_value, Info.LabelSetType);
+ }
+ }
+
+ if ( ASDCP_SUCCESS(result) )
+ result = Writer.OpenWrite(Options.out_file.c_str(), Info, TDesc);
+ }
+
+ if ( ASDCP_FAILURE(result) )
+ return result;
+
+ std::string XMLDoc;
+ TimedText::ResourceList_t::const_iterator ri;
+
+ result = Parser.ReadTimedTextResource(XMLDoc);
+
+ if ( ASDCP_SUCCESS(result) )
+ result = Writer.WriteTimedTextResource(XMLDoc, Context, HMAC);
+
+ for ( ri = TDesc.ResourceList.begin() ; ri != TDesc.ResourceList.end() && ASDCP_SUCCESS(result); ri++ )
+ {
+ result = Parser.ReadAncillaryResource((*ri).ResourceID, FrameBuffer);
+
+ if ( ASDCP_SUCCESS(result) )
+ {
+ if ( Options.verbose_flag )
+ FrameBuffer.Dump(stderr, Options.fb_dump_size);
+
+ if ( ! Options.no_write_flag )
+ {
+ result = Writer.WriteAncillaryResource(FrameBuffer, Context, HMAC);
+
+ // The Writer class will forward the last block of ciphertext
+ // to the encryption context for use as the IV for the next
+ // frame. If you want to use non-sequitur IV values, un-comment
+ // the following line of code.
+ // if ( ASDCP_SUCCESS(result) && Options.key_flag )
+ // Context->SetIVec(RNG.FillRandom(IV_buf, CBC_BLOCK_SIZE));
+ }
+ }
+
+ if ( result == RESULT_ENDOFFILE )
+ result = RESULT_OK;
+ }
+
+ if ( ASDCP_SUCCESS(result) && ! Options.no_write_flag )
+ result = Writer.Finalize();
+
+ return result;
+}
+
//
int
main(int argc, const char** argv)
@@ -666,6 +814,7 @@ main(int argc, const char** argv)
Result_t result = RESULT_OK;
char str_buf[64];
g_dict = &ASDCP::DefaultSMPTEDict();
+ assert(g_dict);
CommandOptions Options(argc, argv);
diff --git a/src/asdcp-info.cpp b/src/asdcp-info.cpp
index 4a03bde..df69d2b 100755
--- a/src/asdcp-info.cpp
+++ b/src/asdcp-info.cpp
@@ -93,7 +93,7 @@ USAGE:%s [-h|-help] [-V]\n\
\n\
Options:\n\
-3 - Force stereoscopic interpretation of a JP2K file\n\
- -C - Do not show essence coding UL\n\
+ -c - Show essence coding UL\n\
-d - Show essence descriptor info\n\
-h | -help - Show help\n\
-H - Show MXF header metadata\n\
@@ -326,7 +326,8 @@ public:
m_Desc.FillDescriptor(m_Reader);
m_Reader.FillWriterInfo(m_WriterInfo);
- fprintf(stdout, "File essence type is %s, (%d edit unit%s).\n",
+ fprintf(stdout, "%s file essence type is %s, (%d edit unit%s).\n",
+ ( m_WriterInfo.LabelSetType == LS_MXF_SMPTE ? "SMPTE 429" : LS_MXF_INTEROP ? "Interop" : "Unknown" ),
type_string, m_Desc.ContainerDuration, (m_Desc.ContainerDuration==1?"":"s"));
if ( Options.showheader_flag )
@@ -488,7 +489,7 @@ public:
}
// scale bytes to megabits
- static const double mega_const = 1 / ( 1024.0 * 1024.0 / 8.0 );
+ static const double mega_const = 1.0 / ( 1000000 / 8.0 );
// we did not accumulate the first or last frame, so duration -= 2
double avg_bytes_frame = total_frame_bytes / ( m_Desc.ContainerDuration - 2 );
diff --git a/src/asdcp-wrap.cpp b/src/asdcp-wrap.cpp
index 04608d3..3bad03e 100755
--- a/src/asdcp-wrap.cpp
+++ b/src/asdcp-wrap.cpp
@@ -222,7 +222,7 @@ public:
byte_t asset_id_value[UUIDlen];// value of asset ID (when asset_id_flag is true)
PCM::ChannelFormat_t channel_fmt; // audio channel arrangement
std::string out_file; //
- bool show_ul_values_flag; /// if true, dump the UL table before going tp work.
+ bool show_ul_values_flag; /// if true, dump the UL table before going to work.
Kumu::PathList_t filenames; // list of filenames to be processed
UL channel_assignment;
UL picture_coding;
@@ -1232,11 +1232,9 @@ write_timed_text_file(CommandOptions& Options)
else
Kumu::GenRandomUUID(Info.AssetUUID);
- if ( Options.use_smpte_labels )
- {
- Info.LabelSetType = LS_MXF_SMPTE;
- fprintf(stderr, "ATTENTION! Writing SMPTE Universal Labels\n");
- }
+ // 428-7 IN 429-5 always uses SMPTE labels
+ Info.LabelSetType = LS_MXF_SMPTE;
+ fprintf(stderr, "ATTENTION! Writing SMPTE Universal Labels\n");
// configure encryption
if( Options.key_flag )
diff --git a/src/h__02_Reader.cpp b/src/h__02_Reader.cpp
index a433026..1a0de11 100644
--- a/src/h__02_Reader.cpp
+++ b/src/h__02_Reader.cpp
@@ -200,9 +200,11 @@ AS_02::MXF::AS02IndexReader::InitFromFile(const Kumu::FileReader& reader, const
for ( ii = m_PacketList->m_List.begin(); ii != m_PacketList->m_List.end(); ++ii )
{
- if ( (*ii)->IsA(OBJ_TYPE_ARGS(IndexTableSegment)) )
+ IndexTableSegment *segment = dynamic_cast<IndexTableSegment*>(*ii);
+
+ if ( segment != 0 )
{
- m_Duration += static_cast<IndexTableSegment*>(*ii)->IndexDuration;
+ m_Duration += segment->IndexDuration;
}
}
}
@@ -263,10 +265,12 @@ AS_02::MXF::AS02IndexReader::InitFromBuffer(const byte_t* p, ui32_t l, const ui6
if ( KM_SUCCESS(result) )
{
- if ( object->IsA(OBJ_TYPE_ARGS(IndexTableSegment)) )
+ IndexTableSegment *segment = dynamic_cast<IndexTableSegment*>(object);
+
+ if ( segment != 0 )
{
- static_cast<IndexTableSegment*>(object)->RtFileOffset = essence_container_offset;
- static_cast<IndexTableSegment*>(object)->RtEntryOffset = body_offset;
+ segment->RtFileOffset = essence_container_offset;
+ segment->RtEntryOffset = body_offset;
m_PacketList->AddPacket(object); // takes ownership
}
else
@@ -340,29 +344,30 @@ AS_02::MXF::AS02IndexReader::Lookup(ui32_t frame_num, ASDCP::MXF::IndexTableSegm
std::list<InterchangeObject*>::iterator li;
for ( li = m_PacketList->m_List.begin(); li != m_PacketList->m_List.end(); li++ )
{
- if ( (*li)->IsA(OBJ_TYPE_ARGS(IndexTableSegment)) )
+ IndexTableSegment *segment = dynamic_cast<IndexTableSegment*>(*li);
+
+ if ( segment != 0 )
{
- IndexTableSegment* Segment = static_cast<IndexTableSegment*>(*li);
- ui64_t start_pos = Segment->IndexStartPosition;
+ ui64_t start_pos = segment->IndexStartPosition;
- if ( Segment->EditUnitByteCount > 0 )
+ if ( segment->EditUnitByteCount > 0 )
{
if ( m_PacketList->m_List.size() > 1 )
DefaultLogSink().Error("Unexpected multiple IndexTableSegment in CBR file\n");
- if ( ! Segment->IndexEntryArray.empty() )
+ if ( ! segment->IndexEntryArray.empty() )
DefaultLogSink().Error("Unexpected IndexEntryArray contents in CBR file\n");
- Entry.StreamOffset = ((ui64_t)frame_num * Segment->EditUnitByteCount) + Segment->RtFileOffset;
+ Entry.StreamOffset = ((ui64_t)frame_num * segment->EditUnitByteCount) + segment->RtFileOffset;
return RESULT_OK;
}
else if ( (ui64_t)frame_num >= start_pos
- && (ui64_t)frame_num < (start_pos + Segment->IndexDuration) )
+ && (ui64_t)frame_num < (start_pos + segment->IndexDuration) )
{
ui64_t tmp = frame_num - start_pos;
assert(tmp <= 0xFFFFFFFFL);
- Entry = Segment->IndexEntryArray[(ui32_t) tmp];
- Entry.StreamOffset = Entry.StreamOffset - Segment->RtEntryOffset + Segment->RtFileOffset;
+ Entry = segment->IndexEntryArray[(ui32_t) tmp];
+ Entry.StreamOffset = Entry.StreamOffset - segment->RtEntryOffset + segment->RtFileOffset;
return RESULT_OK;
}
}
diff --git a/src/h__02_Writer.cpp b/src/h__02_Writer.cpp
index a121142..c81da5c 100644
--- a/src/h__02_Writer.cpp
+++ b/src/h__02_Writer.cpp
@@ -122,23 +122,25 @@ AS_02::MXF::AS02IndexWriter::Dump(FILE* stream)
Partition::Dump(stream);
std::list<InterchangeObject*>::iterator i = m_PacketList->m_List.begin();
- for ( ; i != m_PacketList->m_List.end(); i++ )
- (*i)->Dump(stream);
+ for ( ; i != m_PacketList->m_List.end(); ++i )
+ {
+ (*i)->Dump(stream);
+ }
}
//
ui32_t
AS_02::MXF::AS02IndexWriter::GetDuration() const
{
- ui32_t duration;
+ ui32_t duration = 0;
std::list<InterchangeObject*>::const_iterator i;
for ( i = m_PacketList->m_List.begin(); i != m_PacketList->m_List.end(); ++i )
{
- if ( (*i)->IsA(OBJ_TYPE_ARGS(IndexTableSegment)) )
+ IndexTableSegment* segment = dynamic_cast<IndexTableSegment*>(*i);
+ if ( segment != 0 )
{
- IndexTableSegment& Segment = *(IndexTableSegment*)*i;
- duration += Segment.IndexDuration;
+ duration += segment->IndexEntryArray.size();
}
}
@@ -380,7 +382,6 @@ AS_02::h__AS02Writer::FinalizeClip(ui32_t bytes_per_frame)
Result_t
AS_02::h__AS02Writer::WriteAS02Footer()
{
-
if ( m_IndexWriter.GetDuration() > 0 )
{
m_IndexWriter.ThisPartition = m_File.Tell();