summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/AS_02.h10
-rw-r--r--src/AS_02_JP2K.cpp12
-rw-r--r--src/AS_02_PCM.cpp77
-rw-r--r--src/AS_02_internal.h260
-rwxr-xr-xsrc/AS_DCP.h66
-rw-r--r--src/AS_DCP_ATMOS.cpp16
-rw-r--r--src/AS_DCP_DCData.cpp8
-rw-r--r--src/AS_DCP_DCData_internal.h4
-rwxr-xr-xsrc/AS_DCP_JP2K.cpp16
-rwxr-xr-xsrc/AS_DCP_MPEG2.cpp14
-rwxr-xr-xsrc/AS_DCP_MXF.cpp99
-rwxr-xr-xsrc/AS_DCP_PCM.cpp23
-rw-r--r--src/AS_DCP_TimedText.cpp12
-rwxr-xr-xsrc/AS_DCP_internal.h4
-rw-r--r--src/DCData_ByteStream_Parser.cpp5
-rw-r--r--src/DCData_Sequence_Parser.cpp10
-rwxr-xr-xsrc/JP2K_Codestream_Parser.cpp7
-rwxr-xr-xsrc/JP2K_Sequence_Parser.cpp9
-rw-r--r--src/KM_fileio.cpp62
-rwxr-xr-xsrc/KM_fileio.h12
-rwxr-xr-xsrc/MPEG2_Parser.cpp9
-rwxr-xr-xsrc/MXF.cpp71
-rwxr-xr-xsrc/MXF.h10
-rw-r--r--src/Makefile.am8
-rwxr-xr-xsrc/PCMParserList.cpp6
-rwxr-xr-xsrc/PCMParserList.h4
-rwxr-xr-xsrc/PCM_Parser.cpp8
-rw-r--r--src/TimedText_Parser.cpp22
-rwxr-xr-xsrc/as-02-unwrap.cpp63
-rwxr-xr-xsrc/asdcp-test.cpp3
-rwxr-xr-xsrc/asdcp-wrap.cpp35
-rw-r--r--src/h__02_Reader.cpp7
-rw-r--r--src/h__02_Writer.cpp289
-rwxr-xr-xsrc/h__Reader.cpp2
34 files changed, 704 insertions, 559 deletions
diff --git a/src/AS_02.h b/src/AS_02.h
index 3437152..6b34c77 100644
--- a/src/AS_02.h
+++ b/src/AS_02.h
@@ -97,7 +97,6 @@ namespace AS_02
Result_t Lookup(ui32_t frame_num, ASDCP::MXF::IndexTableSegment::IndexEntry&) const;
};
-
// Returns size in bytes of a single sample of data described by ADesc
inline ui32_t CalcSampleSize(const ASDCP::MXF::WaveAudioDescriptor& d)
@@ -119,7 +118,8 @@ namespace AS_02
}
// Returns number of frames for data described by ADesc, given a duration in samples and an edit rate
- inline ui32_t CalcFramesFromDurationInSamples(const ui32_t durationInSamples, const ASDCP::MXF::WaveAudioDescriptor& d, const ASDCP::Rational& edit_rate)
+ inline ui32_t CalcFramesFromDurationInSamples(const ui32_t durationInSamples, const ASDCP::MXF::WaveAudioDescriptor& d,
+ const ASDCP::Rational& edit_rate)
{
return static_cast<ui32_t>(static_cast<ui64_t>(durationInSamples) *
static_cast<ui64_t>(d.AudioSamplingRate.Denominator * edit_rate.Numerator) /
@@ -142,7 +142,7 @@ namespace AS_02
};
namespace JP2K
- {
+ {
//
class MXFWriter
{
@@ -167,7 +167,7 @@ namespace AS_02
ASDCP::MXF::InterchangeObject_list_t& essence_sub_descriptor_list,
const ASDCP::Rational& edit_rate, const ui32_t& header_size = 16384,
const IndexStrategy_t& strategy = IS_FOLLOW, const ui32_t& partition_space = 10);
-
+
// Writes a frame of essence to the MXF file. If the optional AESEncContext
// argument is present, the essence is encrypted prior to writing.
// Fails if the file is not open, is finalized, or an operating system
@@ -238,7 +238,7 @@ namespace AS_02
// the reader to signal the number of samples to be read by each call to ReadFrame();
//
- class MXFWriter
+ class MXFWriter
{
class h__Writer;
ASDCP::mem_ptr<h__Writer> m_Writer;
diff --git a/src/AS_02_JP2K.cpp b/src/AS_02_JP2K.cpp
index a8eff1a..48b98fe 100644
--- a/src/AS_02_JP2K.cpp
+++ b/src/AS_02_JP2K.cpp
@@ -55,8 +55,6 @@ class AS_02::JP2K::MXFReader::h__Reader : public AS_02::h__AS02Reader
ASDCP_NO_COPY_CONSTRUCT(h__Reader);
public:
- PictureDescriptor m_PDesc; // codestream parameter list
-
h__Reader(const Dictionary& d) :
AS_02::h__AS02Reader(d) {}
@@ -229,7 +227,7 @@ AS_02::JP2K::MXFReader::FillWriterInfo(WriterInfo& Info) const
//------------------------------------------------------------------------------------------
//
-class AS_02::JP2K::MXFWriter::h__Writer : public AS_02::h__AS02Writer
+class AS_02::JP2K::MXFWriter::h__Writer : public AS_02::h__AS02WriterFrame
{
ASDCP_NO_COPY_CONSTRUCT(h__Writer);
h__Writer();
@@ -237,10 +235,9 @@ class AS_02::JP2K::MXFWriter::h__Writer : public AS_02::h__AS02Writer
JPEG2000PictureSubDescriptor* m_EssenceSubDescriptor;
public:
- PictureDescriptor m_PDesc;
byte_t m_EssenceUL[SMPTE_UL_LENGTH];
- h__Writer(const Dictionary& d) : h__AS02Writer(d), m_EssenceSubDescriptor(0) {
+ h__Writer(const Dictionary& d) : h__AS02WriterFrame(d), m_EssenceSubDescriptor(0) {
memset(m_EssenceUL, 0, SMPTE_UL_LENGTH);
}
@@ -334,6 +331,11 @@ AS_02::JP2K::MXFWriter::h__Writer::SetSourceStream(const std::string& label, con
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));
+
+ if ( KM_SUCCESS(result) )
+ {
+ this->m_IndexWriter.SetPrimerLookup(&this->m_HeaderPart.m_Primer);
+ }
}
return result;
diff --git a/src/AS_02_PCM.cpp b/src/AS_02_PCM.cpp
index 2ffc45e..9a6a98c 100644
--- a/src/AS_02_PCM.cpp
+++ b/src/AS_02_PCM.cpp
@@ -49,6 +49,7 @@ class AS_02::PCM::MXFReader::h__Reader : public AS_02::h__AS02Reader
{
ui64_t m_ClipEssenceBegin;
ui64_t m_SamplesPerFrame;
+ ui32_t m_BytesPerFrame;
ui32_t m_ContainerDuration;
ASDCP_NO_COPY_CONSTRUCT(h__Reader);
@@ -56,7 +57,7 @@ class AS_02::PCM::MXFReader::h__Reader : public AS_02::h__AS02Reader
public:
h__Reader(const Dictionary& d) : AS_02::h__AS02Reader(d), m_ClipEssenceBegin(0),
- m_SamplesPerFrame(0), m_ContainerDuration(0) {}
+ m_SamplesPerFrame(0), m_BytesPerFrame(0), m_ContainerDuration(0) {}
virtual ~h__Reader() {}
ASDCP::Result_t OpenRead(const std::string&, const ASDCP::Rational& edit_rate);
@@ -75,17 +76,20 @@ AS_02::PCM::MXFReader::h__Reader::OpenRead(const std::string& filename, const AS
if( KM_SUCCESS(result) )
{
- if ( KM_SUCCESS(m_HeaderPart.GetMDObjectByType(OBJ_TYPE_ARGS(WaveAudioDescriptor),
- reinterpret_cast<InterchangeObject**>(&wave_descriptor))) )
+ InterchangeObject* tmp_obj = 0;
+
+ if ( KM_SUCCESS(m_HeaderPart.GetMDObjectByType(OBJ_TYPE_ARGS(WaveAudioDescriptor), &tmp_obj)) )
{
- if ( wave_descriptor == 0 )
- {
- DefaultLogSink().Error("WaveAudioDescriptor object not found.\n");
- return RESULT_AS02_FORMAT;
- }
+ wave_descriptor = dynamic_cast<ASDCP::MXF::WaveAudioDescriptor*>(tmp_obj);
}
}
+ if ( wave_descriptor == 0 )
+ {
+ DefaultLogSink().Error("WaveAudioDescriptor object not found.\n");
+ result = RESULT_AS02_FORMAT;
+ }
+
if ( KM_SUCCESS(result) )
result = m_IndexAccess.Lookup(0, tmp_entry);
@@ -131,8 +135,9 @@ AS_02::PCM::MXFReader::h__Reader::OpenRead(const std::string& filename, const AS
m_ClipEssenceBegin = m_File.Tell();
m_SamplesPerFrame = AS_02::MXF::CalcSamplesPerFrame(*wave_descriptor, edit_rate);
- m_ContainerDuration = static_cast<ui32_t>(8ULL * reader.Length() /
- (m_SamplesPerFrame * wave_descriptor->ChannelCount * wave_descriptor->QuantizationBits));
+ m_BytesPerFrame = AS_02::MXF::CalcFrameBufferSize(*wave_descriptor, edit_rate);
+ m_ContainerDuration = static_cast<ui32_t>(reader.Length() / ( m_SamplesPerFrame * AS_02::MXF::CalcSampleSize(*wave_descriptor)));
+
}
}
@@ -144,8 +149,6 @@ ASDCP::Result_t
AS_02::PCM::MXFReader::h__Reader::ReadFrame(ui32_t FrameNum, ASDCP::PCM::FrameBuffer& FrameBuf,
ASDCP::AESDecContext* Ctx, ASDCP::HMACContext* HMAC)
{
- ASDCP::MXF::WaveAudioDescriptor* wave_descriptor = 0;
-
if ( ! m_File.IsOpen() )
{
return RESULT_INIT;
@@ -157,23 +160,9 @@ AS_02::PCM::MXFReader::h__Reader::ReadFrame(ui32_t FrameNum, ASDCP::PCM::FrameBu
}
assert(m_ClipEssenceBegin);
+ ui64_t position = m_ClipEssenceBegin + ( FrameNum * m_BytesPerFrame );
Result_t result = RESULT_OK;
- if( KM_SUCCESS(result) )
- {
- if ( KM_SUCCESS(m_HeaderPart.GetMDObjectByType(OBJ_TYPE_ARGS(WaveAudioDescriptor),
- reinterpret_cast<InterchangeObject**>(&wave_descriptor))) )
- {
- if ( wave_descriptor == 0 )
- {
- DefaultLogSink().Error("WaveAudioDescriptor object not found.\n");
- return RESULT_AS02_FORMAT;
- }
- }
- }
-
- ui64_t position = m_ClipEssenceBegin + ( FrameNum * m_SamplesPerFrame * wave_descriptor->ChannelCount * wave_descriptor->BlockAlign );
-
if ( m_File.Tell() != position )
{
result = m_File.Seek(position);
@@ -181,12 +170,12 @@ AS_02::PCM::MXFReader::h__Reader::ReadFrame(ui32_t FrameNum, ASDCP::PCM::FrameBu
if ( KM_SUCCESS(result) )
{
- result = m_File.Read(FrameBuf.Data(), m_SamplesPerFrame * wave_descriptor->ChannelCount * wave_descriptor->BlockAlign);
+ result = m_File.Read(FrameBuf.Data(), m_BytesPerFrame);
}
if ( KM_SUCCESS(result) )
{
- FrameBuf.Size(m_SamplesPerFrame * wave_descriptor->ChannelCount * wave_descriptor->BlockAlign);
+ FrameBuf.Size(m_BytesPerFrame);
}
return result;
@@ -322,7 +311,7 @@ AS_02::PCM::MXFReader::DumpIndex(FILE* stream) const
//------------------------------------------------------------------------------------------
//
-class AS_02::PCM::MXFWriter::h__Writer : public AS_02::h__AS02Writer
+class AS_02::PCM::MXFWriter::h__Writer : public AS_02::h__AS02WriterClip
{
ASDCP_NO_COPY_CONSTRUCT(h__Writer);
h__Writer();
@@ -333,7 +322,7 @@ public:
ui32_t m_BytesPerFrame;
ui32_t m_SamplesPerFrame;
- h__Writer(const Dictionary& d) : AS_02::h__AS02Writer(d), m_WaveAudioDescriptor(0), m_BytesPerFrame(0), m_SamplesPerFrame(0)
+ h__Writer(const Dictionary& d) : AS_02::h__AS02WriterClip(d), m_WaveAudioDescriptor(0), m_BytesPerFrame(0), m_SamplesPerFrame(0)
{
memset(m_EssenceUL, 0, SMPTE_UL_LENGTH);
}
@@ -355,15 +344,15 @@ AS_02::PCM::MXFWriter::h__Writer::OpenWrite(const std::string& filename, ASDCP::
{
assert(essence_descriptor);
- if ( essence_descriptor->GetUL() != UL(m_Dict->ul(MDD_WaveAudioDescriptor)) )
+ m_WaveAudioDescriptor = dynamic_cast<ASDCP::MXF::WaveAudioDescriptor*>(essence_descriptor);
+
+ if ( m_WaveAudioDescriptor == 0 )
{
DefaultLogSink().Error("Essence descriptor is not a WaveAudioDescriptor.\n");
essence_descriptor->Dump();
return RESULT_AS02_FORMAT;
}
- m_WaveAudioDescriptor = reinterpret_cast<ASDCP::MXF::WaveAudioDescriptor*>(essence_descriptor);
-
if ( ! m_State.Test_BEGIN() )
{
return RESULT_STATE;
@@ -420,10 +409,16 @@ AS_02::PCM::MXFWriter::h__Writer::SetSourceStream(const ASDCP::Rational& edit_ra
m_BytesPerFrame = AS_02::MXF::CalcFrameBufferSize(*m_WaveAudioDescriptor, edit_rate);
m_SamplesPerFrame = AS_02::MXF::CalcSamplesPerFrame(*m_WaveAudioDescriptor, edit_rate);
m_WaveAudioDescriptor->ContainerDuration = 0;
-
+ assert(m_BytesPerFrame);
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);
+ m_EssenceDescriptor->SampleRate, derive_timecode_rate_from_edit_rate(edit_rate));
+
+ if ( KM_SUCCESS(result) )
+ {
+ this->m_IndexWriter.SetEditRate(m_WaveAudioDescriptor->AudioSamplingRate,
+ AS_02::MXF::CalcSampleSize(*m_WaveAudioDescriptor));
+ }
}
return result;
@@ -467,7 +462,7 @@ AS_02::PCM::MXFWriter::h__Writer::WriteFrame(const FrameBuffer& frame_buf, AESEn
if ( KM_SUCCESS(result) )
{
- m_FramesWritten++;
+ m_FramesWritten += m_SamplesPerFrame;
}
return result;
@@ -483,14 +478,11 @@ AS_02::PCM::MXFWriter::h__Writer::Finalize()
m_State.Goto_FINAL();
- Result_t result = FinalizeClip(m_BytesPerFrame);
+ Result_t result = FinalizeClip(AS_02::MXF::CalcSampleSize(*m_WaveAudioDescriptor));
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));
+ m_IndexWriter.m_Duration = m_FramesWritten;
WriteAS02Footer();
}
@@ -541,7 +533,6 @@ AS_02::PCM::MXFWriter::RIP()
return m_Writer->m_RIP;
}
-
// Open the file for writing. The file must not exist. Returns error if
// the operation cannot be completed.
ASDCP::Result_t
diff --git a/src/AS_02_internal.h b/src/AS_02_internal.h
index 0a45a24..4bdb64c 100644
--- a/src/AS_02_internal.h
+++ b/src/AS_02_internal.h
@@ -52,95 +52,273 @@ namespace AS_02
void default_md_object_init();
+
+ //
+ class h__AS02Reader : public ASDCP::MXF::TrackFileReader<ASDCP::MXF::OP1aHeader, AS_02::MXF::AS02IndexReader>
+ {
+ ASDCP_NO_COPY_CONSTRUCT(h__AS02Reader);
+ h__AS02Reader();
+
+ public:
+ h__AS02Reader(const ASDCP::Dictionary&);
+ virtual ~h__AS02Reader();
+
+ Result_t OpenMXFRead(const char* filename);
+
+ // USE FRAME WRAPPING...
+ Result_t ReadEKLVFrame(ui32_t FrameNum, ASDCP::FrameBuffer& FrameBuf,
+ const byte_t* EssenceUL, ASDCP::AESDecContext* Ctx, ASDCP::HMACContext* HMAC);
+
+ // OR CLIP WRAPPING...
+ // clip wrapping is handled directly by the essence-specific classes
+ // Result_t ReadyClip(const ui32_t& FrameNum, const byte_t* EssenceUL, ASDCP::AESDecContext* Ctx, ASDCP::HMACContext* HMAC, ui64_t& position);
+ /// Result_t ReadClipBlock(ASDCP::FrameBuffer& FrameBuf, const ui32_t& read_size);
+
+ // NOT BOTH!
+ };
+
+
namespace MXF
{
//
- class AS02IndexWriter : public ASDCP::MXF::Partition
+ class AS02IndexWriterVBR : public ASDCP::MXF::Partition
{
ASDCP::MXF::IndexTableSegment* m_CurrentSegment;
- ui32_t m_BytesPerEditUnit;
ASDCP::MXF::Rational m_EditRate;
- KM_NO_COPY_CONSTRUCT(AS02IndexWriter);
- AS02IndexWriter();
+ KM_NO_COPY_CONSTRUCT(AS02IndexWriterVBR);
+ AS02IndexWriterVBR();
public:
const ASDCP::Dictionary*& m_Dict;
ASDCP::IPrimerLookup* m_Lookup;
- AS02IndexWriter(const ASDCP::Dictionary*&);
- virtual ~AS02IndexWriter();
+ AS02IndexWriterVBR(const ASDCP::Dictionary*&);
+ virtual ~AS02IndexWriterVBR();
+
+ //
+ void SetPrimerLookup(ASDCP::IPrimerLookup* lookup) {
+ assert(lookup);
+ m_Lookup = lookup;
+ }
Result_t WriteToFile(Kumu::FileWriter& Writer);
- void ResetCBR(Kumu::fpos_t offset);
void Dump(FILE* = 0);
ui32_t GetDuration() const;
void PushIndexEntry(const ASDCP::MXF::IndexTableSegment::IndexEntry&);
- void SetIndexParamsCBR(ASDCP::IPrimerLookup* lookup, ui32_t size, const ASDCP::Rational& Rate);
- void SetIndexParamsVBR(ASDCP::IPrimerLookup* lookup, const ASDCP::Rational& Rate, Kumu::fpos_t offset);
};
- }
- //
- class h__AS02Reader : public ASDCP::MXF::TrackFileReader<ASDCP::MXF::OP1aHeader, AS_02::MXF::AS02IndexReader>
- {
- ASDCP_NO_COPY_CONSTRUCT(h__AS02Reader);
- h__AS02Reader();
- public:
- h__AS02Reader(const ASDCP::Dictionary&);
- virtual ~h__AS02Reader();
+ //
+ class AS02IndexWriterCBR : public ASDCP::MXF::Partition
+ {
+ ASDCP::MXF::IndexTableSegment* m_CurrentSegment;
+ ASDCP::MXF::Rational m_EditRate;
- Result_t OpenMXFRead(const char* filename);
+ KM_NO_COPY_CONSTRUCT(AS02IndexWriterCBR);
+ AS02IndexWriterCBR();
- // USE FRAME WRAPPING...
- Result_t ReadEKLVFrame(ui32_t FrameNum, ASDCP::FrameBuffer& FrameBuf,
- const byte_t* EssenceUL, ASDCP::AESDecContext* Ctx, ASDCP::HMACContext* HMAC);
+ public:
+ const ASDCP::Dictionary*& m_Dict;
+ ASDCP::IPrimerLookup* m_Lookup;
+ ui32_t m_Duration;
+ ui32_t m_SampleSize;
+
+ AS02IndexWriterCBR(const ASDCP::Dictionary*&);
+ virtual ~AS02IndexWriterCBR();
- // OR CLIP WRAPPING...
- // clip wrapping is handled directly by the essence-specific classes
- // Result_t ReadyClip(const ui32_t& FrameNum, const byte_t* EssenceUL, ASDCP::AESDecContext* Ctx, ASDCP::HMACContext* HMAC, ui64_t& position);
- /// Result_t ReadClipBlock(ASDCP::FrameBuffer& FrameBuf, const ui32_t& read_size);
+ //
+ void SetPrimerLookup(ASDCP::IPrimerLookup* lookup) {
+ assert(lookup);
+ m_Lookup = lookup;
+ }
- // NOT BOTH!
- };
+ Result_t WriteToFile(Kumu::FileWriter& Writer);
+ ui32_t GetDuration() const;
+ void SetEditRate(const ASDCP::Rational& edit_rate, const ui32_t& sample_size);
+ };
+ }
//
+ template <class IndexWriterType>
class h__AS02Writer : public ASDCP::MXF::TrackFileWriter<ASDCP::MXF::OP1aHeader>
{
ASDCP_NO_COPY_CONSTRUCT(h__AS02Writer);
h__AS02Writer();
public:
- ui64_t m_ECStart; // offset of the first essence element
- ui64_t m_ClipStart; // state variable for clip-wrap-in-progress
ui32_t m_PartitionSpace; // edit units per partition
- AS_02::MXF::AS02IndexWriter m_IndexWriter;
- IndexStrategy_t m_IndexStrategy; // per SMPTE ST 2067-5
+ IndexWriterType m_IndexWriter;
+ ui64_t m_ECStart; // offset of the first essence element
+
+ //
+ h__AS02Writer(const ASDCP::Dictionary& d) :
+ ASDCP::MXF::TrackFileWriter<ASDCP::MXF::OP1aHeader>(d), m_IndexWriter(m_Dict), m_ECStart(0) {}
- h__AS02Writer(const Dictionary&);
- virtual ~h__AS02Writer();
+ ~h__AS02Writer() {}
+
+
// all the above for a single source clip
Result_t WriteAS02Header(const std::string& PackageLabel, const ASDCP::UL& WrappingUL,
const std::string& TrackName, const ASDCP::UL& EssenceUL,
const ASDCP::UL& DataDefinition, const ASDCP::Rational& EditRate,
- ui32_t TCFrameRate, ui32_t BytesPerEditUnit = 0);
+ const ui32_t& TCFrameRate)
+ {
+ if ( EditRate.Numerator == 0 || EditRate.Denominator == 0 )
+ {
+ DefaultLogSink().Error("Non-zero edit-rate reqired.\n");
+ return RESULT_PARAM;
+ }
+
+ InitHeader();
+
+ AddSourceClip(EditRate, EditRate/*TODO: for a moment*/, TCFrameRate, TrackName, EssenceUL, DataDefinition, PackageLabel);
+ AddEssenceDescriptor(WrappingUL);
+
+ this->m_IndexWriter.SetPrimerLookup(&this->m_HeaderPart.m_Primer);
+ this->m_RIP.PairArray.push_back(RIP::Pair(0, 0)); // Header partition RIP entry
+ this->m_IndexWriter.OperationalPattern = this->m_HeaderPart.OperationalPattern;
+ this->m_IndexWriter.EssenceContainers = this->m_HeaderPart.EssenceContainers;
+
+ Result_t result = this->m_HeaderPart.WriteToFile(this->m_File, this->m_HeaderSize);
+
+ if ( KM_SUCCESS(result) )
+ {
+ this->m_PartitionSpace *= floor( EditRate.Quotient() + 0.5 ); // convert seconds to edit units
+ this->m_ECStart = this->m_File.Tell();
+ this->m_IndexWriter.IndexSID = 129;
+
+ UL body_ul(this->m_Dict->ul(MDD_ClosedCompleteBodyPartition));
+ Partition body_part(this->m_Dict);
+ body_part.BodySID = 1;
+ body_part.OperationalPattern = this->m_HeaderPart.OperationalPattern;
+ body_part.EssenceContainers = this->m_HeaderPart.EssenceContainers;
+ body_part.ThisPartition = this->m_ECStart;
+ result = body_part.WriteToFile(this->m_File, body_ul);
+ this->m_RIP.PairArray.push_back(RIP::Pair(1, body_part.ThisPartition)); // Second RIP Entry
+ }
+
+ return result;
+ }
+
+ // standard method of writing the header and footer of a completed AS-02 file
+ //
+ Result_t WriteAS02Footer()
+ {
+ if ( this->m_IndexWriter.GetDuration() > 0 )
+ {
+ this->m_IndexWriter.ThisPartition = this->m_File.Tell();
+ this->m_IndexWriter.WriteToFile(this->m_File);
+ this->m_RIP.PairArray.push_back(RIP::Pair(0, this->m_IndexWriter.ThisPartition));
+ }
+
+ // update all Duration properties
+ ASDCP::MXF::Partition footer_part(this->m_Dict);
+ DurationElementList_t::iterator dli = this->m_DurationUpdateList.begin();
+
+ for (; dli != this->m_DurationUpdateList.end(); ++dli )
+ {
+ **dli = this->m_FramesWritten;
+ }
+
+ this->m_EssenceDescriptor->ContainerDuration = this->m_FramesWritten;
+ footer_part.PreviousPartition = this->m_RIP.PairArray.back().ByteOffset;
+
+ Kumu::fpos_t here = this->m_File.Tell();
+ this->m_RIP.PairArray.push_back(RIP::Pair(0, here)); // Last RIP Entry
+ this->m_HeaderPart.FooterPartition = here;
+
+ assert(this->m_Dict);
+ footer_part.OperationalPattern = this->m_HeaderPart.OperationalPattern;
+ footer_part.EssenceContainers = this->m_HeaderPart.EssenceContainers;
+ footer_part.FooterPartition = here;
+ footer_part.ThisPartition = here;
+
+ UL footer_ul(this->m_Dict->ul(MDD_CompleteFooter));
+ Result_t result = footer_part.WriteToFile(this->m_File, footer_ul);
+
+ if ( KM_SUCCESS(result) )
+ result = this->m_RIP.WriteToFile(this->m_File);
+
+ if ( KM_SUCCESS(result) )
+ result = this->m_File.Seek(0);
+
+ if ( KM_SUCCESS(result) )
+ result = m_HeaderPart.WriteToFile(this->m_File, this->m_HeaderSize);
+
+ if ( KM_SUCCESS(result) )
+ {
+ ASDCP::MXF::Array<ASDCP::MXF::RIP::Pair>::const_iterator i = this->m_RIP.PairArray.begin();
+ ui64_t header_byte_count = this->m_HeaderPart.HeaderByteCount;
+ ui64_t previous_partition = 0;
+
+ for ( i = this->m_RIP.PairArray.begin(); KM_SUCCESS(result) && i != this->m_RIP.PairArray.end(); ++i )
+ {
+ ASDCP::MXF::Partition plain_part(this->m_Dict);
+ result = this->m_File.Seek(i->ByteOffset);
+
+ if ( KM_SUCCESS(result) )
+ result = plain_part.InitFromFile(this->m_File);
+
+ if ( KM_SUCCESS(result)
+ && ( plain_part.IndexSID > 0 || plain_part.BodySID > 0 ) )
+ {
+ plain_part.PreviousPartition = previous_partition;
+ plain_part.FooterPartition = footer_part.ThisPartition;
+ previous_partition = plain_part.ThisPartition;
+ result = this->m_File.Seek(i->ByteOffset);
+
+ if ( KM_SUCCESS(result) )
+ {
+ UL tmp_ul = plain_part.GetUL();
+ result = plain_part.WriteToFile(this->m_File, tmp_ul);
+ }
+ }
+ }
+ }
+
+ this->m_File.Close();
+ return result;
+ }
+ };
+
+ //
+ class h__AS02WriterFrame : public h__AS02Writer<AS_02::MXF::AS02IndexWriterVBR>
+ {
+ ASDCP_NO_COPY_CONSTRUCT(h__AS02WriterFrame);
+ h__AS02WriterFrame();
+
+ public:
+ IndexStrategy_t m_IndexStrategy; // per SMPTE ST 2067-5
+
+ h__AS02WriterFrame(const Dictionary&);
+ virtual ~h__AS02WriterFrame();
- // USE FRAME WRAPPING...
Result_t WriteEKLVPacket(const ASDCP::FrameBuffer& FrameBuf,const byte_t* EssenceUL,
AESEncContext* Ctx, HMACContext* HMAC);
+ };
+
+ //
+ class h__AS02WriterClip : public h__AS02Writer<AS_02::MXF::AS02IndexWriterCBR>
+ {
+ ASDCP_NO_COPY_CONSTRUCT(h__AS02WriterClip);
+ h__AS02WriterClip();
+
+ public:
+ ui64_t m_ECStart; // offset of the first essence element
+ ui64_t m_ClipStart; // state variable for clip-wrap-in-progress
+ // AS_02::MXF::AS02IndexWriterCBR m_IndexWriter;
+ IndexStrategy_t m_IndexStrategy; // per SMPTE ST 2067-5
+
+ h__AS02WriterClip(const Dictionary&);
+ virtual ~h__AS02WriterClip();
- // OR CLIP WRAPPING...
bool HasOpenClip() const;
Result_t StartClip(const byte_t* EssenceUL, AESEncContext* Ctx, HMACContext* HMAC);
Result_t WriteClipBlock(const ASDCP::FrameBuffer& FrameBuf);
Result_t FinalizeClip(ui32_t bytes_per_frame);
-
- // NOT BOTH!
-
- Result_t WriteAS02Footer();
};
} // namespace AS_02
diff --git a/src/AS_DCP.h b/src/AS_DCP.h
index 6f99698..6b598cc 100755
--- a/src/AS_DCP.h
+++ b/src/AS_DCP.h
@@ -208,8 +208,12 @@ namespace ASDCP {
// The file accessors in this library implement a bounded set of essence types.
// This list will be expanded when support for new types is added to the library.
enum EssenceType_t {
- ESS_UNKNOWN, // the file is not a supported AS-DCP essence container
- ESS_MPEG2_VES, // the file contains an MPEG video elementary stream
+ ESS_UNKNOWN, // the file is not a supported AS-DCP of AS-02 essence container
+
+ //
+ ESS_MPEG2_VES, // the file contains an MPEG-2 video elementary stream
+
+ // d-cinema essence types
ESS_JPEG_2000, // the file contains one or more JPEG 2000 codestreams
ESS_PCM_24b_48k, // the file contains one or more PCM audio pairs
ESS_PCM_24b_96k, // the file contains one or more PCM audio pairs
@@ -217,18 +221,25 @@ namespace ASDCP {
ESS_JPEG_2000_S, // the file contains one or more JPEG 2000 codestream pairs (stereoscopic)
ESS_DCDATA_UNKNOWN, // the file contains one or more D-Cinema Data bytestreams
ESS_DCDATA_DOLBY_ATMOS, // the file contains one or more DolbyATMOS bytestreams
+
+ // IMF essence types
+ ESS_AS02_JPEG_2000, // the file contains one or more JPEG 2000 codestreams
+ ESS_AS02_PCM_24b_48k, // the file contains one or more PCM audio pairs, clip wrapped
+ ESS_AS02_PCM_24b_96k, // the file contains one or more PCM audio pairs, clip wrapped
+ ESS_AS02_TIMED_TEXT, // the file contains a TTML document and zero or more resources
+
ESS_MAX
};
// Determine the type of essence contained in the given MXF file. RESULT_OK
// is returned if the file is successfully opened and contains a valid MXF
// stream. If there is an error, the result code will indicate the reason.
- Result_t EssenceType(const char* filename, EssenceType_t& type);
+ Result_t EssenceType(const std::string& filename, EssenceType_t& type);
// Determine the type of essence contained in the given raw file. RESULT_OK
// is returned if the file is successfully opened and contains a known
// stream type. If there is an error, the result code will indicate the reason.
- Result_t RawEssenceType(const char* filename, EssenceType_t& type);
+ Result_t RawEssenceType(const std::string& filename, EssenceType_t& type);
//---------------------------------------------------------------------------------
@@ -707,7 +718,7 @@ namespace ASDCP {
// Opens the stream for reading, parses enough data to provide a complete
// set of stream metadata for the MXFWriter below.
- Result_t OpenRead(const char* filename) const;
+ Result_t OpenRead(const std::string& filename) const;
// Fill a VideoDescriptor struct with the values from the file's header.
// Returns RESULT_INIT if the file is not open.
@@ -745,7 +756,7 @@ namespace ASDCP {
// 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 char* filename, const WriterInfo&,
+ Result_t OpenWrite(const std::string& filename, const WriterInfo&,
const VideoDescriptor&, ui32_t HeaderSize = 16384);
// Writes a frame of essence to the MXF file. If the optional AESEncContext
@@ -777,7 +788,7 @@ namespace ASDCP {
// Open the file for reading. The file must exist. Returns error if the
// operation cannot be completed.
- Result_t OpenRead(const char* filename) const;
+ Result_t OpenRead(const std::string& filename) const;
// Returns RESULT_INIT if the file is not open.
Result_t Close() const;
@@ -848,6 +859,7 @@ namespace ASDCP {
CF_CFG_3, // 7.1 (SDDS) with optional HI/VI
CF_CFG_4, // Wild Track Format
CF_CFG_5, // 7.1 DS with optional HI/VI
+ CF_CFG_6, // ST 377-4 (MCA) labels (see also ASDCP::MXF::decode_mca_string)
CF_MAXIMUM
};
@@ -918,7 +930,7 @@ namespace ASDCP {
// Opens the stream for reading, parses enough data to provide a complete
// set of stream metadata for the MXFWriter below. PictureRate controls
// ther frame rate for the MXF frame wrapping option.
- Result_t OpenRead(const char* filename, const Rational& PictureRate) const;
+ Result_t OpenRead(const std::string& filename, const Rational& PictureRate) const;
// Fill an AudioDescriptor struct with the values from the file's header.
// Returns RESULT_INIT if the file is not open.
@@ -953,7 +965,7 @@ namespace ASDCP {
// 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 char* filename, const WriterInfo&,
+ Result_t OpenWrite(const std::string& filename, const WriterInfo&,
const AudioDescriptor&, ui32_t HeaderSize = 16384);
// Writes a frame of essence to the MXF file. If the optional AESEncContext
@@ -985,7 +997,7 @@ namespace ASDCP {
// Open the file for reading. The file must exist. Returns error if the
// operation cannot be completed.
- Result_t OpenRead(const char* filename) const;
+ Result_t OpenRead(const std::string& filename) const;
// Returns RESULT_INIT if the file is not open.
Result_t Close() const;
@@ -1124,7 +1136,7 @@ namespace ASDCP {
// The frame buffer's PlaintextOffset parameter will be set to the first
// byte of the data segment. Set this value to zero if you want
// encrypted headers.
- Result_t OpenReadFrame(const char* filename, FrameBuffer&) const;
+ Result_t OpenReadFrame(const std::string& filename, FrameBuffer&) const;
// Fill a PictureDescriptor struct with the values from the file's codestream.
// Returns RESULT_INIT if the file is not open.
@@ -1154,7 +1166,7 @@ namespace ASDCP {
// MXFWriter below. If the "pedantic" parameter is given and is true, the
// parser will check the metadata for each codestream and fail if a
// mismatch is detected.
- Result_t OpenRead(const char* filename, bool pedantic = false) const;
+ Result_t OpenRead(const std::string& filename, bool pedantic = false) const;
// Opens a file sequence for reading. The sequence is expected to contain one or
// more filenames, each naming a file containing the codestream for exactly one
@@ -1202,7 +1214,7 @@ namespace ASDCP {
// 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 char* filename, const WriterInfo&,
+ Result_t OpenWrite(const std::string& filename, const WriterInfo&,
const PictureDescriptor&, ui32_t HeaderSize = 16384);
// Writes a frame of essence to the MXF file. If the optional AESEncContext
@@ -1234,7 +1246,7 @@ namespace ASDCP {
// Open the file for reading. The file must exist. Returns error if the
// operation cannot be completed.
- Result_t OpenRead(const char* filename) const;
+ Result_t OpenRead(const std::string& filename) const;
// Returns RESULT_INIT if the file is not open.
Result_t Close() const;
@@ -1307,7 +1319,7 @@ namespace ASDCP {
// 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 char* filename, const WriterInfo&,
+ Result_t OpenWrite(const std::string& filename, const WriterInfo&,
const PictureDescriptor&, ui32_t HeaderSize = 16384);
// Writes a pair of frames of essence to the MXF file. If the optional AESEncContext
@@ -1349,7 +1361,7 @@ namespace ASDCP {
// Open the file for reading. The file must exist. Returns error if the
// operation cannot be completed.
- Result_t OpenRead(const char* filename) const;
+ Result_t OpenRead(const std::string& filename) const;
// Returns RESULT_INIT if the file is not open.
Result_t Close() const;
@@ -1486,12 +1498,12 @@ namespace ASDCP {
// Opens an XML file for reading, parses data to provide a complete
// set of stream metadata for the MXFWriter below.
- Result_t OpenRead(const char* filename) const;
+ Result_t OpenRead(const std::string& filename) const;
// Parses an XML document to provide a complete set of stream metadata
// for the MXFWriter below. The optional filename argument is used to
// initialize the default resource resolver (see ReadAncillaryResource).
- Result_t OpenRead(const std::string& xml_doc, const char* filename = 0) const;
+ 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.
@@ -1531,7 +1543,7 @@ namespace ASDCP {
// 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 char* filename, const WriterInfo&,
+ Result_t OpenWrite(const std::string& filename, const WriterInfo&,
const TimedTextDescriptor&, ui32_t HeaderSize = 16384);
// Writes the Timed-Text Resource to the MXF file. The file must be UTF-8
@@ -1573,7 +1585,7 @@ namespace ASDCP {
// Open the file for reading. The file must exist. Returns error if the
// operation cannot be completed.
- Result_t OpenRead(const char* filename) const;
+ Result_t OpenRead(const std::string& filename) const;
// Returns RESULT_INIT if the file is not open.
Result_t Close() const;
@@ -1662,7 +1674,7 @@ namespace ASDCP {
// The frame buffer's PlaintextOffset parameter will be set to the first
// byte of the data segment. Set this value to zero if you want
// encrypted headers.
- Result_t OpenReadFrame(const char* filename, FrameBuffer&) const;
+ Result_t OpenReadFrame(const std::string& filename, FrameBuffer&) const;
// Fill a DCDataDescriptor struct with the values from the file's bytestream.
// Returns RESULT_INIT if the file is not open.
@@ -1684,7 +1696,7 @@ namespace ASDCP {
// more files, each containing the bytestream for exactly one frame. The files
// must be named such that the frames are in temporal order when sorted
// alphabetically by filename.
- Result_t OpenRead(const char* filename) const;
+ Result_t OpenRead(const std::string& filename) const;
// Opens a file sequence for reading. The sequence is expected to contain one or
// more filenames, each naming a file containing the bytestream for exactly one
@@ -1727,7 +1739,7 @@ namespace ASDCP {
// 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 char* filename, const WriterInfo&,
+ Result_t OpenWrite(const std::string& filename, const WriterInfo&,
const DCDataDescriptor&, ui32_t HeaderSize = 16384);
// Writes a frame of essence to the MXF file. If the optional AESEncContext
@@ -1759,7 +1771,7 @@ namespace ASDCP {
// Open the file for reading. The file must exist. Returns error if the
// operation cannot be completed.
- Result_t OpenRead(const char* filename) const;
+ Result_t OpenRead(const std::string& filename) const;
// Returns RESULT_INIT if the file is not open.
Result_t Close() const;
@@ -1812,7 +1824,7 @@ namespace ASDCP {
// Print debugging information to stream (stderr default)
void AtmosDescriptorDump(const AtmosDescriptor&, FILE* = 0);
// Determine if a file is a raw atmos file
- bool IsDolbyAtmos(const char* filename);
+ bool IsDolbyAtmos(const std::string& filename);
//
class MXFWriter
@@ -1835,7 +1847,7 @@ namespace ASDCP {
// 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 char* filename, const WriterInfo&,
+ Result_t OpenWrite(const std::string& filename, const WriterInfo&,
const AtmosDescriptor&, ui32_t HeaderSize = 16384);
// Writes a frame of essence to the MXF file. If the optional AESEncContext
@@ -1867,7 +1879,7 @@ namespace ASDCP {
// Open the file for reading. The file must exist. Returns error if the
// operation cannot be completed.
- Result_t OpenRead(const char* filename) const;
+ Result_t OpenRead(const std::string& filename) const;
// Returns RESULT_INIT if the file is not open.
Result_t Close() const;
diff --git a/src/AS_DCP_ATMOS.cpp b/src/AS_DCP_ATMOS.cpp
index e8a2a8a..7fa8c09 100644
--- a/src/AS_DCP_ATMOS.cpp
+++ b/src/AS_DCP_ATMOS.cpp
@@ -93,11 +93,11 @@ ASDCP::ATMOS::AtmosDescriptorDump(const AtmosDescriptor& ADesc, FILE* stream)
//
bool
-ASDCP::ATMOS::IsDolbyAtmos(const char* filename)
+ASDCP::ATMOS::IsDolbyAtmos(const std::string& filename)
{
// TODO
// For now use an atmos extension
- bool result = (0 == (std::string("atmos").compare(Kumu::PathGetExtension(std::string(filename)))));
+ bool result = ( 0 == (std::string("atmos").compare(Kumu::PathGetExtension(filename))) );
return result;
}
@@ -118,7 +118,7 @@ class ASDCP::ATMOS::MXFReader::h__Reader : public ASDCP::DCData::h__Reader
h__Reader(const Dictionary& d) : DCData::h__Reader(d), m_EssenceSubDescriptor(NULL),
m_ADesc() {}
virtual ~h__Reader() {}
- Result_t OpenRead(const char*);
+ Result_t OpenRead(const std::string&);
Result_t MD_to_Atmos_ADesc(ATMOS::AtmosDescriptor& ADesc);
};
@@ -142,7 +142,7 @@ ASDCP::ATMOS::MXFReader::h__Reader::MD_to_Atmos_ADesc(ATMOS::AtmosDescriptor& AD
//
//
ASDCP::Result_t
-ASDCP::ATMOS::MXFReader::h__Reader::OpenRead(const char* filename)
+ASDCP::ATMOS::MXFReader::h__Reader::OpenRead(const std::string& filename)
{
Result_t result = DCData::h__Reader::OpenRead(filename);
@@ -234,7 +234,7 @@ ASDCP::ATMOS::MXFReader::RIP()
// Open the file for reading. The file must exist. Returns error if the
// operation cannot be completed.
ASDCP::Result_t
-ASDCP::ATMOS::MXFReader::OpenRead(const char* filename) const
+ASDCP::ATMOS::MXFReader::OpenRead(const std::string& filename) const
{
return m_Reader->OpenRead(filename);
}
@@ -334,7 +334,7 @@ class ASDCP::ATMOS::MXFWriter::h__Writer : public DCData::h__Writer
virtual ~h__Writer(){}
- Result_t OpenWrite(const char*, ui32_t HeaderSize, const AtmosDescriptor& ADesc);
+ Result_t OpenWrite(const std::string&, ui32_t HeaderSize, const AtmosDescriptor& ADesc);
Result_t Atmos_ADesc_to_MD(const AtmosDescriptor& ADesc);
};
@@ -355,7 +355,7 @@ ASDCP::ATMOS::MXFWriter::h__Writer::Atmos_ADesc_to_MD(const AtmosDescriptor& ADe
//
ASDCP::Result_t
-ASDCP::ATMOS::MXFWriter::h__Writer::OpenWrite(const char* filename, ui32_t HeaderSize, const AtmosDescriptor& ADesc)
+ASDCP::ATMOS::MXFWriter::h__Writer::OpenWrite(const std::string& filename, ui32_t HeaderSize, const AtmosDescriptor& ADesc)
{
m_EssenceSubDescriptor = new DolbyAtmosSubDescriptor(m_Dict);
@@ -436,7 +436,7 @@ ASDCP::ATMOS::MXFWriter::RIP()
// Open the file for writing. The file must not exist. Returns error if
// the operation cannot be completed.
ASDCP::Result_t
-ASDCP::ATMOS::MXFWriter::OpenWrite(const char* filename, const WriterInfo& Info,
+ASDCP::ATMOS::MXFWriter::OpenWrite(const std::string& filename, const WriterInfo& Info,
const AtmosDescriptor& ADesc, ui32_t HeaderSize)
{
if ( Info.LabelSetType != LS_MXF_SMPTE )
diff --git a/src/AS_DCP_DCData.cpp b/src/AS_DCP_DCData.cpp
index a1bb043..e145e1f 100644
--- a/src/AS_DCP_DCData.cpp
+++ b/src/AS_DCP_DCData.cpp
@@ -91,7 +91,7 @@ ASDCP::DCData::h__Reader::MD_to_DCData_DDesc(DCData::DCDataDescriptor& DDesc)
//
//
ASDCP::Result_t
-ASDCP::DCData::h__Reader::OpenRead(const char* filename)
+ASDCP::DCData::h__Reader::OpenRead(const std::string& filename)
{
Result_t result = OpenMXFRead(filename);
@@ -244,7 +244,7 @@ ASDCP::DCData::MXFReader::RIP()
// Open the file for reading. The file must exist. Returns error if the
// operation cannot be completed.
ASDCP::Result_t
-ASDCP::DCData::MXFReader::OpenRead(const char* filename) const
+ASDCP::DCData::MXFReader::OpenRead(const std::string& filename) const
{
return m_Reader->OpenRead(filename);
}
@@ -346,7 +346,7 @@ ASDCP::DCData::h__Writer::DCData_DDesc_to_MD(DCData::DCDataDescriptor& DDesc)
//
ASDCP::Result_t
-ASDCP::DCData::h__Writer::OpenWrite(char const* filename, ui32_t HeaderSize,
+ASDCP::DCData::h__Writer::OpenWrite(const std::string& filename, ui32_t HeaderSize,
const SubDescriptorList_t& subDescriptors)
{
if ( ! m_State.Test_BEGIN() )
@@ -534,7 +534,7 @@ ASDCP::DCData::MXFWriter::RIP()
// Open the file for writing. The file must not exist. Returns error if
// the operation cannot be completed.
ASDCP::Result_t
-ASDCP::DCData::MXFWriter::OpenWrite(const char* filename, const WriterInfo& Info,
+ASDCP::DCData::MXFWriter::OpenWrite(const std::string& filename, const WriterInfo& Info,
const DCDataDescriptor& DDesc, ui32_t HeaderSize)
{
if ( Info.LabelSetType != LS_MXF_SMPTE )
diff --git a/src/AS_DCP_DCData_internal.h b/src/AS_DCP_DCData_internal.h
index 93ccb7e..a9e510d 100644
--- a/src/AS_DCP_DCData_internal.h
+++ b/src/AS_DCP_DCData_internal.h
@@ -60,7 +60,7 @@ namespace DCData
h__Reader(const Dictionary& d) : ASDCP::h__ASDCPReader(d), m_EssenceDescriptor(0),
m_DDesc() {}
~h__Reader() {}
- Result_t OpenRead(const char*);
+ Result_t OpenRead(const std::string&);
Result_t ReadFrame(ui32_t, FrameBuffer&, AESDecContext*, HMACContext*);
Result_t MD_to_DCData_DDesc(DCData::DCDataDescriptor& DDesc);
};
@@ -80,7 +80,7 @@ namespace DCData
~h__Writer(){}
- Result_t OpenWrite(const char*, ui32_t HeaderSize, const SubDescriptorList_t& subDescriptors);
+ Result_t OpenWrite(const std::string&, ui32_t HeaderSize, const SubDescriptorList_t& subDescriptors);
Result_t SetSourceStream(const DCDataDescriptor&, const byte_t*, const std::string&, const std::string&);
Result_t WriteFrame(const FrameBuffer&, AESEncContext* = 0, HMACContext* = 0);
Result_t Finalize();
diff --git a/src/AS_DCP_JP2K.cpp b/src/AS_DCP_JP2K.cpp
index 1b3bc54..62c9e78 100755
--- a/src/AS_DCP_JP2K.cpp
+++ b/src/AS_DCP_JP2K.cpp
@@ -339,7 +339,7 @@ public:
virtual ~lh__Reader() {}
- Result_t OpenRead(const char*, EssenceType_t);
+ Result_t OpenRead(const std::string&, EssenceType_t);
Result_t ReadFrame(ui32_t, JP2K::FrameBuffer&, AESDecContext*, HMACContext*);
};
@@ -347,7 +347,7 @@ public:
//
//
ASDCP::Result_t
-lh__Reader::OpenRead(const char* filename, EssenceType_t type)
+lh__Reader::OpenRead(const std::string& filename, EssenceType_t type)
{
Result_t result = OpenMXFRead(filename);
@@ -582,7 +582,7 @@ ASDCP::JP2K::MXFReader::RIP()
// Open the file for reading. The file must exist. Returns error if the
// operation cannot be completed.
ASDCP::Result_t
-ASDCP::JP2K::MXFReader::OpenRead(const char* filename) const
+ASDCP::JP2K::MXFReader::OpenRead(const std::string& filename) const
{
return m_Reader->OpenRead(filename, ASDCP::ESS_JPEG_2000);
}
@@ -809,7 +809,7 @@ ASDCP::JP2K::MXFSReader::RIP()
// Open the file for reading. The file must exist. Returns error if the
// operation cannot be completed.
ASDCP::Result_t
-ASDCP::JP2K::MXFSReader::OpenRead(const char* filename) const
+ASDCP::JP2K::MXFSReader::OpenRead(const std::string& filename) const
{
return m_Reader->OpenRead(filename, ASDCP::ESS_JPEG_2000_S);
}
@@ -929,7 +929,7 @@ public:
virtual ~lh__Writer(){}
- Result_t OpenWrite(const char*, EssenceType_t type, ui32_t HeaderSize);
+ Result_t OpenWrite(const std::string&, EssenceType_t type, ui32_t HeaderSize);
Result_t SetSourceStream(const PictureDescriptor&, const std::string& label,
ASDCP::Rational LocalEditRate = ASDCP::Rational(0,0));
Result_t WriteFrame(const JP2K::FrameBuffer&, bool add_index, AESEncContext*, HMACContext*);
@@ -939,7 +939,7 @@ public:
// Open the file for writing. The file must not exist. Returns error if
// the operation cannot be completed.
ASDCP::Result_t
-lh__Writer::OpenWrite(const char* filename, EssenceType_t type, ui32_t HeaderSize)
+lh__Writer::OpenWrite(const std::string& filename, EssenceType_t type, ui32_t HeaderSize)
{
if ( ! m_State.Test_BEGIN() )
return RESULT_STATE;
@@ -1137,7 +1137,7 @@ ASDCP::JP2K::MXFWriter::RIP()
// Open the file for writing. The file must not exist. Returns error if
// the operation cannot be completed.
ASDCP::Result_t
-ASDCP::JP2K::MXFWriter::OpenWrite(const char* filename, const WriterInfo& Info,
+ASDCP::JP2K::MXFWriter::OpenWrite(const std::string& filename, const WriterInfo& Info,
const PictureDescriptor& PDesc, ui32_t HeaderSize)
{
if ( Info.LabelSetType == LS_MXF_SMPTE )
@@ -1283,7 +1283,7 @@ ASDCP::JP2K::MXFSWriter::RIP()
// Open the file for writing. The file must not exist. Returns error if
// the operation cannot be completed.
ASDCP::Result_t
-ASDCP::JP2K::MXFSWriter::OpenWrite(const char* filename, const WriterInfo& Info,
+ASDCP::JP2K::MXFSWriter::OpenWrite(const std::string& filename, const WriterInfo& Info,
const PictureDescriptor& PDesc, ui32_t HeaderSize)
{
if ( Info.LabelSetType == LS_MXF_SMPTE )
diff --git a/src/AS_DCP_MPEG2.cpp b/src/AS_DCP_MPEG2.cpp
index 21991bf..8353ea4 100755
--- a/src/AS_DCP_MPEG2.cpp
+++ b/src/AS_DCP_MPEG2.cpp
@@ -170,7 +170,7 @@ public:
h__Reader(const Dictionary& d) : ASDCP::h__ASDCPReader(d) {}
virtual ~h__Reader() {}
- Result_t OpenRead(const char*);
+ Result_t OpenRead(const std::string&);
Result_t ReadFrame(ui32_t, FrameBuffer&, AESDecContext*, HMACContext*);
Result_t ReadFrameGOPStart(ui32_t, FrameBuffer&, AESDecContext*, HMACContext*);
Result_t FindFrameGOPStart(ui32_t, ui32_t&);
@@ -181,7 +181,7 @@ public:
//
//
ASDCP::Result_t
-ASDCP::MPEG2::MXFReader::h__Reader::OpenRead(const char* filename)
+ASDCP::MPEG2::MXFReader::h__Reader::OpenRead(const std::string& filename)
{
Result_t result = OpenMXFRead(filename);
@@ -385,7 +385,7 @@ ASDCP::MPEG2::MXFReader::RIP()
// Open the file for reading. The file must exist. Returns error if the
// operation cannot be completed.
ASDCP::Result_t
-ASDCP::MPEG2::MXFReader::OpenRead(const char* filename) const
+ASDCP::MPEG2::MXFReader::OpenRead(const std::string& filename) const
{
return m_Reader->OpenRead(filename);
}
@@ -521,7 +521,7 @@ public:
virtual ~h__Writer(){}
- Result_t OpenWrite(const char*, ui32_t HeaderSize);
+ Result_t OpenWrite(const std::string&, ui32_t HeaderSize);
Result_t SetSourceStream(const VideoDescriptor&);
Result_t WriteFrame(const FrameBuffer&, AESEncContext* = 0, HMACContext* = 0);
Result_t Finalize();
@@ -531,7 +531,7 @@ public:
// Open the file for writing. The file must not exist. Returns error if
// the operation cannot be completed.
ASDCP::Result_t
-ASDCP::MPEG2::MXFWriter::h__Writer::OpenWrite(const char* filename, ui32_t HeaderSize)
+ASDCP::MPEG2::MXFWriter::h__Writer::OpenWrite(const std::string& filename, ui32_t HeaderSize)
{
if ( ! m_State.Test_BEGIN() )
return RESULT_STATE;
@@ -568,6 +568,8 @@ ASDCP::MPEG2::MXFWriter::h__Writer::SetSourceStream(const VideoDescriptor& VDesc
if ( ASDCP_SUCCESS(result) )
{
+ m_FooterPart.SetDeltaParams(IndexTableSegment::DeltaEntry(-1, 0, 0));
+
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));
@@ -711,7 +713,7 @@ ASDCP::MPEG2::MXFWriter::RIP()
// Open the file for writing. The file must not exist. Returns error if
// the operation cannot be completed.
ASDCP::Result_t
-ASDCP::MPEG2::MXFWriter::OpenWrite(const char* filename, const WriterInfo& Info,
+ASDCP::MPEG2::MXFWriter::OpenWrite(const std::string& filename, const WriterInfo& Info,
const VideoDescriptor& VDesc, ui32_t HeaderSize)
{
if ( Info.LabelSetType == LS_MXF_SMPTE )
diff --git a/src/AS_DCP_MXF.cpp b/src/AS_DCP_MXF.cpp
index f3ad310..82ec81c 100755
--- a/src/AS_DCP_MXF.cpp
+++ b/src/AS_DCP_MXF.cpp
@@ -161,14 +161,12 @@ ASDCP::MD_to_CryptoInfo(CryptographicContext* InfoObj, WriterInfo& Info, const D
//
//
ASDCP::Result_t
-ASDCP::EssenceType(const char* filename, EssenceType_t& type)
+ASDCP::EssenceType(const std::string& filename, EssenceType_t& type)
{
const Dictionary* m_Dict = &DefaultCompositeDict();
InterchangeObject* md_object = 0;
assert(m_Dict);
-
- ASDCP_TEST_NULL_STR(filename);
Kumu::FileReader Reader;
OP1aHeader TestHeader(m_Dict);
@@ -180,47 +178,80 @@ ASDCP::EssenceType(const char* filename, EssenceType_t& type)
if ( ASDCP_SUCCESS(result) )
{
type = ESS_UNKNOWN;
- if ( ASDCP_SUCCESS(TestHeader.GetMDObjectByType(OBJ_TYPE_ARGS(JPEG2000PictureSubDescriptor))) )
+
+ if ( TestHeader.OperationalPattern == UL(m_Dict->ul(MDD_OPAtom))
+ || TestHeader.OperationalPattern == UL(m_Dict->ul(MDD_MXFInterop_OPAtom)) )
{
- if ( ASDCP_SUCCESS(TestHeader.GetMDObjectByType(OBJ_TYPE_ARGS(StereoscopicPictureSubDescriptor))) )
+ if ( ASDCP_SUCCESS(TestHeader.GetMDObjectByType(OBJ_TYPE_ARGS(JPEG2000PictureSubDescriptor))) )
{
- type = ESS_JPEG_2000_S;
+ if ( ASDCP_SUCCESS(TestHeader.GetMDObjectByType(OBJ_TYPE_ARGS(StereoscopicPictureSubDescriptor))) )
+ {
+ type = ESS_JPEG_2000_S;
+ }
+ else
+ {
+ type = ESS_JPEG_2000;
+ }
}
- else
+ else if ( ASDCP_SUCCESS(TestHeader.GetMDObjectByType(OBJ_TYPE_ARGS(WaveAudioDescriptor), &md_object)) )
{
- type = ESS_JPEG_2000;
+ assert(md_object);
+ if ( static_cast<ASDCP::MXF::WaveAudioDescriptor*>(md_object)->AudioSamplingRate == SampleRate_96k )
+ {
+ type = ESS_PCM_24b_96k;
+ }
+ else
+ {
+ type = ESS_PCM_24b_48k;
+ }
}
- }
- else if ( ASDCP_SUCCESS(TestHeader.GetMDObjectByType(OBJ_TYPE_ARGS(WaveAudioDescriptor), &md_object)) )
- {
- assert(md_object);
- if ( static_cast<ASDCP::MXF::WaveAudioDescriptor*>(md_object)->AudioSamplingRate == SampleRate_96k )
+ else if ( ASDCP_SUCCESS(TestHeader.GetMDObjectByType(OBJ_TYPE_ARGS(MPEG2VideoDescriptor))) )
{
- type = ESS_PCM_24b_96k;
+ type = ESS_MPEG2_VES;
}
- else
+ else if ( ASDCP_SUCCESS(TestHeader.GetMDObjectByType(OBJ_TYPE_ARGS(TimedTextDescriptor))) )
{
- type = ESS_PCM_24b_48k;
+ type = ESS_TIMED_TEXT;
+ }
+ else if ( ASDCP_SUCCESS(TestHeader.GetMDObjectByType(OBJ_TYPE_ARGS(DCDataDescriptor))) )
+ {
+ if ( ASDCP_SUCCESS(TestHeader.GetMDObjectByType(OBJ_TYPE_ARGS(DolbyAtmosSubDescriptor))) )
+ {
+ type = ESS_DCDATA_DOLBY_ATMOS;
+ }
+ else
+ {
+ type = ESS_DCDATA_UNKNOWN;
+ }
}
}
- else if ( ASDCP_SUCCESS(TestHeader.GetMDObjectByType(OBJ_TYPE_ARGS(MPEG2VideoDescriptor))) )
- {
- type = ESS_MPEG2_VES;
- }
- else if ( ASDCP_SUCCESS(TestHeader.GetMDObjectByType(OBJ_TYPE_ARGS(TimedTextDescriptor))) )
- {
- type = ESS_TIMED_TEXT;
- }
- else if ( ASDCP_SUCCESS(TestHeader.GetMDObjectByType(OBJ_TYPE_ARGS(DCDataDescriptor))) )
+ else if ( TestHeader.OperationalPattern == UL(m_Dict->ul(MDD_OP1a)) )
{
- if ( ASDCP_SUCCESS(TestHeader.GetMDObjectByType(OBJ_TYPE_ARGS(DolbyAtmosSubDescriptor))) )
+ if ( ASDCP_SUCCESS(TestHeader.GetMDObjectByType(OBJ_TYPE_ARGS(JPEG2000PictureSubDescriptor))) )
{
- type = ESS_DCDATA_DOLBY_ATMOS;
+ type = ESS_AS02_JPEG_2000;
}
- else
+ else if ( ASDCP_SUCCESS(TestHeader.GetMDObjectByType(OBJ_TYPE_ARGS(WaveAudioDescriptor), &md_object)) )
{
- type = ESS_DCDATA_UNKNOWN;
+ assert(md_object);
+ if ( static_cast<ASDCP::MXF::WaveAudioDescriptor*>(md_object)->AudioSamplingRate == SampleRate_96k )
+ {
+ type = ESS_AS02_PCM_24b_96k;
+ }
+ else
+ {
+ type = ESS_AS02_PCM_24b_48k;
+ }
}
+ else if ( ASDCP_SUCCESS(TestHeader.GetMDObjectByType(OBJ_TYPE_ARGS(TimedTextDescriptor))) )
+ {
+ type = ESS_AS02_TIMED_TEXT;
+ }
+ }
+ else
+ {
+ DefaultLogSink().Error("Unsupported MXF Operational Pattern.\n");
+ return RESULT_FORMAT;
}
}
@@ -229,9 +260,8 @@ ASDCP::EssenceType(const char* filename, EssenceType_t& type)
//
ASDCP::Result_t
-ASDCP::RawEssenceType(const char* filename, EssenceType_t& type)
+ASDCP::RawEssenceType(const std::string& filename, EssenceType_t& type)
{
- ASDCP_TEST_NULL_STR(filename);
type = ESS_UNKNOWN;
ASDCP::FrameBuffer FB;
Kumu::FileReader Reader;
@@ -317,10 +347,7 @@ ASDCP::RawEssenceType(const char* filename, EssenceType_t& type)
if ( next_file[0] == '.' ) // no hidden files or internal links
continue;
- std::string Str(filename);
- Str += "/";
- Str += next_file;
- result = Reader.OpenRead(Str.c_str());
+ result = Reader.OpenRead(Kumu::PathJoin(filename, next_file));
if ( ASDCP_SUCCESS(result) )
{
@@ -354,7 +381,7 @@ ASDCP::RawEssenceType(const char* filename, EssenceType_t& type)
return RESULT_FORMAT;
}
}
- else if ( ASDCP::ATMOS::IsDolbyAtmos(Str.c_str()) )
+ else if ( ASDCP::ATMOS::IsDolbyAtmos(Kumu::PathJoin(filename, next_file)) )
{
type = ESS_DCDATA_DOLBY_ATMOS;
}
diff --git a/src/AS_DCP_PCM.cpp b/src/AS_DCP_PCM.cpp
index 8011a55..88ccd1f 100755
--- a/src/AS_DCP_PCM.cpp
+++ b/src/AS_DCP_PCM.cpp
@@ -77,6 +77,10 @@ ASDCP::PCM_ADesc_to_MD(PCM::AudioDescriptor& ADesc, MXF::WaveAudioDescriptor* AD
case PCM::CF_CFG_5:
ADescObj->ChannelAssignment = DefaultSMPTEDict().Type(MDD_DCAudioChannelCfg_5_7p1_DS).ul;
break;
+
+ case PCM::CF_CFG_6:
+ ADescObj->ChannelAssignment = DefaultSMPTEDict().Type(MDD_DCAudioChannelCfg_MCA).ul;
+ break;
}
return RESULT_OK;
@@ -116,6 +120,9 @@ ASDCP::MD_to_PCM_ADesc(MXF::WaveAudioDescriptor* ADescObj, PCM::AudioDescriptor&
else if ( ADescObj->ChannelAssignment == DefaultSMPTEDict().Type(MDD_DCAudioChannelCfg_5_7p1_DS).ul )
ADesc.ChannelFormat = PCM::CF_CFG_5;
+
+ else if ( ADescObj->ChannelAssignment == DefaultSMPTEDict().Type(MDD_DCAudioChannelCfg_MCA).ul )
+ ADesc.ChannelFormat = PCM::CF_CFG_6;
}
return RESULT_OK;
@@ -161,6 +168,10 @@ ASDCP::PCM::operator << (std::ostream& strm, const AudioDescriptor& ADesc)
case CF_CFG_5:
strm << "Config 5 (7.1 DS with optional HI/VI)";
break;
+
+ case CF_CFG_6:
+ strm << "Config 6 (ST 377-1 MCA)";
+ break;
}
strm << std::endl;
@@ -237,7 +248,7 @@ public:
h__Reader(const Dictionary& d) : ASDCP::h__ASDCPReader(d) {}
virtual ~h__Reader() {}
- Result_t OpenRead(const char*);
+ Result_t OpenRead(const std::string&);
Result_t ReadFrame(ui32_t, FrameBuffer&, AESDecContext*, HMACContext*);
};
@@ -245,7 +256,7 @@ public:
//
//
ASDCP::Result_t
-ASDCP::PCM::MXFReader::h__Reader::OpenRead(const char* filename)
+ASDCP::PCM::MXFReader::h__Reader::OpenRead(const std::string& filename)
{
Result_t result = OpenMXFRead(filename);
@@ -397,7 +408,7 @@ ASDCP::PCM::MXFReader::RIP()
// Open the file for reading. The file must exist. Returns error if the
// operation cannot be completed.
ASDCP::Result_t
-ASDCP::PCM::MXFReader::OpenRead(const char* filename) const
+ASDCP::PCM::MXFReader::OpenRead(const std::string& filename) const
{
return m_Reader->OpenRead(filename);
}
@@ -500,7 +511,7 @@ public:
virtual ~h__Writer(){}
- Result_t OpenWrite(const char*, ui32_t HeaderSize);
+ Result_t OpenWrite(const std::string&, ui32_t HeaderSize);
Result_t SetSourceStream(const AudioDescriptor&);
Result_t WriteFrame(const FrameBuffer&, AESEncContext* = 0, HMACContext* = 0);
Result_t Finalize();
@@ -511,7 +522,7 @@ public:
// Open the file for writing. The file must not exist. Returns error if
// the operation cannot be completed.
ASDCP::Result_t
-ASDCP::PCM::MXFWriter::h__Writer::OpenWrite(const char* filename, ui32_t HeaderSize)
+ASDCP::PCM::MXFWriter::h__Writer::OpenWrite(const std::string& filename, ui32_t HeaderSize)
{
if ( ! m_State.Test_BEGIN() )
return RESULT_STATE;
@@ -682,7 +693,7 @@ ASDCP::PCM::MXFWriter::RIP()
// Open the file for writing. The file must not exist. Returns error if
// the operation cannot be completed.
ASDCP::Result_t
-ASDCP::PCM::MXFWriter::OpenWrite(const char* filename, const WriterInfo& Info,
+ASDCP::PCM::MXFWriter::OpenWrite(const std::string& filename, const WriterInfo& Info,
const AudioDescriptor& ADesc, ui32_t HeaderSize)
{
if ( Info.LabelSetType == LS_MXF_SMPTE )
diff --git a/src/AS_DCP_TimedText.cpp b/src/AS_DCP_TimedText.cpp
index e5425b4..e158cde 100644
--- a/src/AS_DCP_TimedText.cpp
+++ b/src/AS_DCP_TimedText.cpp
@@ -139,7 +139,7 @@ public:
virtual ~h__Reader() {}
- Result_t OpenRead(const char*);
+ Result_t OpenRead(const std::string&);
Result_t MD_to_TimedText_TDesc(TimedText::TimedTextDescriptor& TDesc);
Result_t ReadTimedTextResource(FrameBuffer& FrameBuf, AESDecContext* Ctx, HMACContext* HMAC);
Result_t ReadAncillaryResource(const byte_t*, FrameBuffer& FrameBuf, AESDecContext* Ctx, HMACContext* HMAC);
@@ -201,7 +201,7 @@ ASDCP::TimedText::MXFReader::h__Reader::MD_to_TimedText_TDesc(TimedText::TimedTe
//
ASDCP::Result_t
-ASDCP::TimedText::MXFReader::h__Reader::OpenRead(char const* filename)
+ASDCP::TimedText::MXFReader::h__Reader::OpenRead(const std::string& filename)
{
Result_t result = OpenMXFRead(filename);
@@ -385,7 +385,7 @@ ASDCP::TimedText::MXFReader::RIP()
// Open the file for reading. The file must exist. Returns error if the
// operation cannot be completed.
ASDCP::Result_t
-ASDCP::TimedText::MXFReader::OpenRead(const char* filename) const
+ASDCP::TimedText::MXFReader::OpenRead(const std::string& filename) const
{
return m_Reader->OpenRead(filename);
}
@@ -506,7 +506,7 @@ public:
virtual ~h__Writer() {}
- Result_t OpenWrite(const char*, ui32_t HeaderSize);
+ Result_t OpenWrite(const std::string&, ui32_t HeaderSize);
Result_t SetSourceStream(const TimedTextDescriptor&);
Result_t WriteTimedTextResource(const std::string& XMLDoc, AESEncContext* = 0, HMACContext* = 0);
Result_t WriteAncillaryResource(const FrameBuffer&, AESEncContext* = 0, HMACContext* = 0);
@@ -532,7 +532,7 @@ ASDCP::TimedText::MXFWriter::h__Writer::TimedText_TDesc_to_MD(TimedText::TimedTe
//
ASDCP::Result_t
-ASDCP::TimedText::MXFWriter::h__Writer::OpenWrite(char const* filename, ui32_t HeaderSize)
+ASDCP::TimedText::MXFWriter::h__Writer::OpenWrite(const std::string& filename, ui32_t HeaderSize)
{
if ( ! m_State.Test_BEGIN() )
return RESULT_STATE;
@@ -749,7 +749,7 @@ ASDCP::TimedText::MXFWriter::RIP()
// Open the file for writing. The file must not exist. Returns error if
// the operation cannot be completed.
ASDCP::Result_t
-ASDCP::TimedText::MXFWriter::OpenWrite(const char* filename, const WriterInfo& Info,
+ASDCP::TimedText::MXFWriter::OpenWrite(const std::string& filename, const WriterInfo& Info,
const TimedTextDescriptor& TDesc, ui32_t HeaderSize)
{
if ( Info.LabelSetType != LS_MXF_SMPTE )
diff --git a/src/AS_DCP_internal.h b/src/AS_DCP_internal.h
index 675f96d..24020e5 100755
--- a/src/AS_DCP_internal.h
+++ b/src/AS_DCP_internal.h
@@ -213,7 +213,7 @@ namespace ASDCP
const MXF::RIP& GetRIP() const { return m_RIP; }
//
- Result_t OpenMXFRead(const char* filename)
+ Result_t OpenMXFRead(const std::string& filename)
{
m_LastPosition = 0;
Result_t result = m_File.OpenRead(filename);
@@ -803,7 +803,7 @@ namespace ASDCP
h__ASDCPReader(const Dictionary&);
virtual ~h__ASDCPReader();
- Result_t OpenMXFRead(const char* filename);
+ Result_t OpenMXFRead(const std::string& filename);
Result_t ReadEKLVFrame(ui32_t FrameNum, ASDCP::FrameBuffer& FrameBuf,
const byte_t* EssenceUL, AESDecContext* Ctx, HMACContext* HMAC);
Result_t LocateFrame(ui32_t FrameNum, Kumu::fpos_t& streamOffset,
diff --git a/src/DCData_ByteStream_Parser.cpp b/src/DCData_ByteStream_Parser.cpp
index 73565d4..28e1869 100644
--- a/src/DCData_ByteStream_Parser.cpp
+++ b/src/DCData_ByteStream_Parser.cpp
@@ -52,9 +52,8 @@ public:
~h__BytestreamParser() {}
- Result_t OpenReadFrame(const char* filename, FrameBuffer& FB)
+ Result_t OpenReadFrame(const std::string& filename, FrameBuffer& FB)
{
- ASDCP_TEST_NULL_STR(filename);
m_File.Close();
Result_t result = m_File.OpenRead(filename);
@@ -95,7 +94,7 @@ ASDCP::DCData::BytestreamParser::~BytestreamParser()
// Opens the stream for reading, parses enough data to provide a complete
// set of stream metadata for the MXFWriter below.
ASDCP::Result_t
-ASDCP::DCData::BytestreamParser::OpenReadFrame(const char* filename, FrameBuffer& FB) const
+ASDCP::DCData::BytestreamParser::OpenReadFrame(const std::string& filename, FrameBuffer& FB) const
{
const_cast<ASDCP::DCData::BytestreamParser*>(this)->m_Parser = new h__BytestreamParser;
return m_Parser->OpenReadFrame(filename, FB);
diff --git a/src/DCData_Sequence_Parser.cpp b/src/DCData_Sequence_Parser.cpp
index 45594c5..de9f39a 100644
--- a/src/DCData_Sequence_Parser.cpp
+++ b/src/DCData_Sequence_Parser.cpp
@@ -66,7 +66,7 @@ class ASDCP::DCData::FileList : public std::list<std::string>
}
//
- Result_t InitFromDirectory(const char* path)
+ Result_t InitFromDirectory(const std::string& path)
{
char next_file[Kumu::MaxFilePath];
Kumu::DirScanner Scanner;
@@ -125,7 +125,7 @@ class ASDCP::DCData::SequenceParser::h__SequenceParser
Close();
}
- Result_t OpenRead(const char* filename);
+ Result_t OpenRead(const std::string& filename);
Result_t OpenRead(const std::list<std::string>& file_list);
void Close() {}
@@ -174,10 +174,8 @@ ASDCP::DCData::SequenceParser::h__SequenceParser::OpenRead()
//
ASDCP::Result_t
-ASDCP::DCData::SequenceParser::h__SequenceParser::OpenRead(const char* filename)
+ASDCP::DCData::SequenceParser::h__SequenceParser::OpenRead(const std::string& filename)
{
- ASDCP_TEST_NULL_STR(filename);
-
Result_t result = m_FileList.InitFromDirectory(filename);
if ( ASDCP_SUCCESS(result) )
@@ -228,7 +226,7 @@ ASDCP::DCData::SequenceParser::~SequenceParser()
// Opens the stream for reading, parses enough data to provide a complete
// set of stream metadata for the MXFWriter below.
ASDCP::Result_t
-ASDCP::DCData::SequenceParser::OpenRead(const char* filename) const
+ASDCP::DCData::SequenceParser::OpenRead(const std::string& filename) const
{
const_cast<ASDCP::DCData::SequenceParser*>(this)->m_Parser = new h__SequenceParser;
diff --git a/src/JP2K_Codestream_Parser.cpp b/src/JP2K_Codestream_Parser.cpp
index a1385d1..c820646 100755
--- a/src/JP2K_Codestream_Parser.cpp
+++ b/src/JP2K_Codestream_Parser.cpp
@@ -1,5 +1,5 @@
/*
-Copyright (c) 2004-2009, John Hurst
+Copyright (c) 2004-2013, John Hurst
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -55,9 +55,8 @@ public:
~h__CodestreamParser() {}
- Result_t OpenReadFrame(const char* filename, FrameBuffer& FB)
+ Result_t OpenReadFrame(const std::string& filename, FrameBuffer& FB)
{
- ASDCP_TEST_NULL_STR(filename);
m_File.Close();
Result_t result = m_File.OpenRead(filename);
@@ -198,7 +197,7 @@ ASDCP::JP2K::CodestreamParser::~CodestreamParser()
// Opens the stream for reading, parses enough data to provide a complete
// set of stream metadata for the MXFWriter below.
ASDCP::Result_t
-ASDCP::JP2K::CodestreamParser::OpenReadFrame(const char* filename, FrameBuffer& FB) const
+ASDCP::JP2K::CodestreamParser::OpenReadFrame(const std::string& filename, FrameBuffer& FB) const
{
const_cast<ASDCP::JP2K::CodestreamParser*>(this)->m_Parser = new h__CodestreamParser;
return m_Parser->OpenReadFrame(filename, FB);
diff --git a/src/JP2K_Sequence_Parser.cpp b/src/JP2K_Sequence_Parser.cpp
index c33321e..a0fd5d0 100755
--- a/src/JP2K_Sequence_Parser.cpp
+++ b/src/JP2K_Sequence_Parser.cpp
@@ -59,7 +59,7 @@ public:
}
//
- Result_t InitFromDirectory(const char* path)
+ Result_t InitFromDirectory(const std::string& path)
{
char next_file[Kumu::MaxFilePath];
Kumu::DirScanner Scanner;
@@ -119,7 +119,7 @@ public:
Close();
}
- Result_t OpenRead(const char* filename, bool pedantic);
+ Result_t OpenRead(const std::string& filename, bool pedantic);
Result_t OpenRead(const std::list<std::string>& file_list, bool pedantic);
void Close() {}
@@ -168,9 +168,8 @@ ASDCP::JP2K::SequenceParser::h__SequenceParser::OpenRead()
//
ASDCP::Result_t
-ASDCP::JP2K::SequenceParser::h__SequenceParser::OpenRead(const char* filename, bool pedantic)
+ASDCP::JP2K::SequenceParser::h__SequenceParser::OpenRead(const std::string& filename, bool pedantic)
{
- ASDCP_TEST_NULL_STR(filename);
m_Pedantic = pedantic;
Result_t result = m_FileList.InitFromDirectory(filename);
@@ -327,7 +326,7 @@ ASDCP::JP2K::SequenceParser::~SequenceParser()
// Opens the stream for reading, parses enough data to provide a complete
// set of stream metadata for the MXFWriter below.
ASDCP::Result_t
-ASDCP::JP2K::SequenceParser::OpenRead(const char* filename, bool pedantic) const
+ASDCP::JP2K::SequenceParser::OpenRead(const std::string& filename, bool pedantic) const
{
const_cast<ASDCP::JP2K::SequenceParser*>(this)->m_Parser = new h__SequenceParser;
diff --git a/src/KM_fileio.cpp b/src/KM_fileio.cpp
index fdd4719..0866acd 100644
--- a/src/KM_fileio.cpp
+++ b/src/KM_fileio.cpp
@@ -684,9 +684,8 @@ Kumu::FileWriter::Writev(const byte_t* buf, ui32_t buf_len)
//
Kumu::Result_t
-Kumu::FileReader::OpenRead(const char* filename) const
+Kumu::FileReader::OpenRead(const std::string& filename) const
{
- KM_TEST_NULL_STR_L(filename);
const_cast<FileReader*>(this)->m_Filename = filename;
// suppress popup window on error
@@ -809,15 +808,14 @@ Kumu::FileReader::Read(byte_t* buf, ui32_t buf_len, ui32_t* read_count) const
//
Kumu::Result_t
-Kumu::FileWriter::OpenWrite(const char* filename)
+Kumu::FileWriter::OpenWrite(const std::string& filename)
{
- KM_TEST_NULL_STR_L(filename);
m_Filename = filename;
// suppress popup window on error
UINT prev = ::SetErrorMode(SEM_FAILCRITICALERRORS|SEM_NOOPENFILEERRORBOX);
- m_Handle = ::CreateFileA(filename,
+ m_Handle = ::CreateFileA(filename.c_str(),
(GENERIC_WRITE|GENERIC_READ), // open for reading
FILE_SHARE_READ, // share for reading
NULL, // no security
@@ -908,11 +906,10 @@ Kumu::FileWriter::Write(const byte_t* buf, ui32_t buf_len, ui32_t* bytes_written
//
Kumu::Result_t
-Kumu::FileReader::OpenRead(const char* filename) const
+Kumu::FileReader::OpenRead(const std::string& filename) const
{
- KM_TEST_NULL_STR_L(filename);
const_cast<FileReader*>(this)->m_Filename = filename;
- const_cast<FileReader*>(this)->m_Handle = open(filename, O_RDONLY, 0);
+ const_cast<FileReader*>(this)->m_Handle = open(filename.c_str(), O_RDONLY, 0);
return ( m_Handle == -1L ) ? RESULT_FILEOPEN : RESULT_OK;
}
@@ -988,15 +985,14 @@ Kumu::FileReader::Read(byte_t* buf, ui32_t buf_len, ui32_t* read_count) const
//
Kumu::Result_t
-Kumu::FileWriter::OpenWrite(const char* filename)
+Kumu::FileWriter::OpenWrite(const std::string& filename)
{
- KM_TEST_NULL_STR_L(filename);
m_Filename = filename;
- m_Handle = open(filename, O_RDWR|O_CREAT|O_TRUNC, 0664);
+ m_Handle = open(filename.c_str(), O_RDWR|O_CREAT|O_TRUNC, 0664);
if ( m_Handle == -1L )
{
- DefaultLogSink().Error("Error opening file %s: %s\n", filename, strerror(errno));
+ DefaultLogSink().Error("Error opening file %s: %s\n", filename.c_str(), strerror(errno));
return RESULT_FILEOPEN;
}
@@ -1006,15 +1002,14 @@ Kumu::FileWriter::OpenWrite(const char* filename)
//
Kumu::Result_t
-Kumu::FileWriter::OpenModify(const char* filename)
+Kumu::FileWriter::OpenModify(const std::string& filename)
{
- KM_TEST_NULL_STR_L(filename);
m_Filename = filename;
- m_Handle = open(filename, O_RDWR|O_CREAT, 0664);
+ m_Handle = open(filename.c_str(), O_RDWR|O_CREAT, 0664);
if ( m_Handle == -1L )
{
- DefaultLogSink().Error("Error opening file %s: %s\n", filename, strerror(errno));
+ DefaultLogSink().Error("Error opening file %s: %s\n", filename.c_str(), strerror(errno));
return RESULT_FILEOPEN;
}
@@ -1080,15 +1075,13 @@ Kumu::FileWriter::Write(const byte_t* buf, ui32_t buf_len, ui32_t* bytes_written
//
Kumu::Result_t
-Kumu::ReadFileIntoString(const char* filename, std::string& outString, ui32_t max_size)
+Kumu::ReadFileIntoString(const std::string& filename, std::string& outString, ui32_t max_size)
{
fsize_t fsize = 0;
ui32_t read_size = 0;
FileReader File;
ByteString ReadBuf;
- KM_TEST_NULL_STR_L(filename);
-
Result_t result = File.OpenRead(filename);
if ( KM_SUCCESS(result) )
@@ -1097,13 +1090,13 @@ Kumu::ReadFileIntoString(const char* filename, std::string& outString, ui32_t ma
if ( fsize > (Kumu::fpos_t)max_size )
{
- DefaultLogSink().Error("%s: exceeds available buffer size (%u)\n", filename, max_size);
+ DefaultLogSink().Error("%s: exceeds available buffer size (%u)\n", filename.c_str(), max_size);
return RESULT_ALLOC;
}
if ( fsize == 0 )
{
- DefaultLogSink().Error("%s: zero file size\n", filename);
+ DefaultLogSink().Error("%s: zero file size\n", filename.c_str());
return RESULT_READFAIL;
}
@@ -1122,11 +1115,10 @@ Kumu::ReadFileIntoString(const char* filename, std::string& outString, ui32_t ma
//
Kumu::Result_t
-Kumu::WriteStringIntoFile(const char* filename, const std::string& inString)
+Kumu::WriteStringIntoFile(const std::string& filename, const std::string& inString)
{
FileWriter File;
ui32_t write_count = 0;
- KM_TEST_NULL_STR_L(filename);
Result_t result = File.OpenWrite(filename);
@@ -1152,7 +1144,7 @@ Kumu::ReadFileIntoObject(const std::string& Filename, Kumu::IArchive& Object, ui
ui32_t read_count = 0;
FileWriter Reader;
- result = Reader.OpenRead(Filename.c_str());
+ result = Reader.OpenRead(Filename);
if ( KM_SUCCESS(result) )
result = Reader.Read(Buffer.Data(), file_size, &read_count);
@@ -1187,7 +1179,7 @@ Kumu::WriteObjectIntoFile(const Kumu::IArchive& Object, const std::string& Filen
if ( KM_SUCCESS(result) )
{
Buffer.Length(MemWriter.Length());
- result = Writer.OpenWrite(Filename.c_str());
+ result = Writer.OpenWrite(Filename);
}
if ( KM_SUCCESS(result) )
@@ -1212,7 +1204,7 @@ Kumu::ReadFileIntoBuffer(const std::string& Filename, Kumu::ByteString& Buffer,
ui32_t read_count = 0;
FileWriter Reader;
- result = Reader.OpenRead(Filename.c_str());
+ result = Reader.OpenRead(Filename);
if ( KM_SUCCESS(result) )
result = Reader.Read(Buffer.Data(), file_size, &read_count);
@@ -1236,7 +1228,7 @@ Kumu::WriteBufferIntoFile(const Kumu::ByteString& Buffer, const std::string& Fil
ui32_t write_count = 0;
FileWriter Writer;
- Result_t result = Writer.OpenWrite(Filename.c_str());
+ Result_t result = Writer.OpenWrite(Filename);
if ( KM_SUCCESS(result) )
result = Writer.Write(Buffer.RoData(), Buffer.Length(), &write_count);
@@ -1261,18 +1253,16 @@ Kumu::DirScanner::DirScanner(void) : m_Handle(-1) {}
//
//
Result_t
-Kumu::DirScanner::Open(const char* filename)
+Kumu::DirScanner::Open(const std::string& filename)
{
- KM_TEST_NULL_STR_L(filename);
-
// we need to append a '*' to read the entire directory
- ui32_t fn_len = strlen(filename);
+ ui32_t fn_len = filename.size();
char* tmp_file = (char*)malloc(fn_len + 8);
if ( tmp_file == 0 )
return RESULT_ALLOC;
- strcpy(tmp_file, filename);
+ strcpy(tmp_file, filename.c_str());
char* p = &tmp_file[fn_len] - 1;
if ( *p != '/' && *p != '\\' )
@@ -1348,13 +1338,11 @@ Kumu::DirScanner::DirScanner(void) : m_Handle(NULL) {}
//
Result_t
-Kumu::DirScanner::Open(const char* filename)
+Kumu::DirScanner::Open(const std::string& dirname)
{
- KM_TEST_NULL_STR_L(filename);
-
Result_t result = RESULT_OK;
- if ( ( m_Handle = opendir(filename) ) == NULL )
+ if ( ( m_Handle = opendir(dirname.c_str()) ) == NULL )
{
switch ( errno )
{
@@ -1370,7 +1358,7 @@ Kumu::DirScanner::Open(const char* filename)
case ENFILE:
result = RESULT_STATE;
default:
- DefaultLogSink().Error("DirScanner::Open(%s): %s\n", filename, strerror(errno));
+ DefaultLogSink().Error("DirScanner::Open(%s): %s\n", dirname.c_str(), strerror(errno));
result = RESULT_FAIL;
}
}
diff --git a/src/KM_fileio.h b/src/KM_fileio.h
index a051e8e..46e2000 100755
--- a/src/KM_fileio.h
+++ b/src/KM_fileio.h
@@ -65,7 +65,7 @@ namespace Kumu
DirScanner(void);
~DirScanner() { Close(); }
- Result_t Open(const char*);
+ Result_t Open(const std::string&);
Result_t Close();
Result_t GetNext(char*);
};
@@ -242,10 +242,10 @@ namespace Kumu
// Instant IO for strings
//
// Reads an entire file into a string.
- Result_t ReadFileIntoString(const char* filename, std::string& outString, ui32_t max_size = 8 * Megabyte);
+ Result_t ReadFileIntoString(const std::string& filename, std::string& outString, ui32_t max_size = 8 * Megabyte);
// Writes a string to a file, overwrites the existing file if present.
- Result_t WriteStringIntoFile(const char* filename, const std::string& inString);
+ Result_t WriteStringIntoFile(const std::string& filename, const std::string& inString);
// Instant IO for archivable objects
//
@@ -282,7 +282,7 @@ namespace Kumu
FileReader() : m_Handle(INVALID_HANDLE_VALUE) {}
virtual ~FileReader() { Close(); }
- Result_t OpenRead(const char*) const; // open the file for reading
+ Result_t OpenRead(const std::string&) const; // open the file for reading
Result_t Close() const; // close the file
fsize_t Size() const; // returns the file's current size
Result_t Seek(Kumu::fpos_t = 0, SeekPos_t = SP_BEGIN) const; // move the file pointer
@@ -312,8 +312,8 @@ namespace Kumu
FileWriter();
virtual ~FileWriter();
- Result_t OpenWrite(const char*); // open a new file, overwrites existing
- Result_t OpenModify(const char*); // open a file for read/write
+ Result_t OpenWrite(const std::string&); // open a new file, overwrites existing
+ Result_t OpenModify(const std::string&); // open a file for read/write
// this part of the interface takes advantage of the iovec structure on
// platforms that support it. For each call to Writev(const byte_t*, ui32_t, ui32_t*),
diff --git a/src/MPEG2_Parser.cpp b/src/MPEG2_Parser.cpp
index 140a53f..89abbfd 100755
--- a/src/MPEG2_Parser.cpp
+++ b/src/MPEG2_Parser.cpp
@@ -371,7 +371,7 @@ public:
h__Parser() : m_TmpBuffer(VESReadSize*8) {}
~h__Parser() { Close(); }
- Result_t OpenRead(const char* filename);
+ Result_t OpenRead(const std::string& filename);
void Close();
Result_t Reset();
Result_t ReadFrame(FrameBuffer&);
@@ -399,9 +399,8 @@ ASDCP::MPEG2::Parser::h__Parser::Close()
//
ASDCP::Result_t
-ASDCP::MPEG2::Parser::h__Parser::OpenRead(const char* filename)
+ASDCP::MPEG2::Parser::h__Parser::OpenRead(const std::string& filename)
{
- ASDCP_TEST_NULL_STR(filename)
ui32_t read_count = 0;
Result_t result = m_FileReader.OpenRead(filename);
@@ -443,7 +442,7 @@ ASDCP::MPEG2::Parser::h__Parser::OpenRead(const char* filename)
if ( ASDCP_FAILURE(result) )
{
- DefaultLogSink().Error("Unable to identify a wrapping mode for the essence in file \"%s\"\n", filename);
+ DefaultLogSink().Error("Unable to identify a wrapping mode for the essence in file \"%s\"\n", filename.c_str());
m_FileReader.Close();
}
@@ -566,7 +565,7 @@ ASDCP::MPEG2::Parser::~Parser()
// Opens the stream for reading, parses enough data to provide a complete
// set of stream metadata for the MXFWriter below.
ASDCP::Result_t
-ASDCP::MPEG2::Parser::OpenRead(const char* filename) const
+ASDCP::MPEG2::Parser::OpenRead(const std::string& filename) const
{
const_cast<ASDCP::MPEG2::Parser*>(this)->m_Parser = new h__Parser;
diff --git a/src/MXF.cpp b/src/MXF.cpp
index 02bf1e9..ac4bb1d 100755
--- a/src/MXF.cpp
+++ b/src/MXF.cpp
@@ -694,7 +694,7 @@ ASDCP::MXF::OP1aHeader::~OP1aHeader() {}
ASDCP::Result_t
ASDCP::MXF::OP1aHeader::InitFromFile(const Kumu::FileReader& Reader)
{
- Result_t result = result = Partition::InitFromFile(Reader);
+ Result_t result = Partition::InitFromFile(Reader);
if ( ASDCP_FAILURE(result) )
return result;
@@ -714,10 +714,15 @@ ASDCP::MXF::OP1aHeader::InitFromFile(const Kumu::FileReader& Reader)
// slurp up the remainder of the header
if ( HeaderByteCount < 1024 )
- DefaultLogSink().Warn("Improbably small HeaderByteCount value: %u\n", HeaderByteCount);
-
- assert (HeaderByteCount <= 0xFFFFFFFFL);
- result = m_HeaderData.Capacity((ui32_t)HeaderByteCount);
+ {
+ DefaultLogSink().Warn("Improbably small HeaderByteCount value: %qu\n", HeaderByteCount);
+ }
+ else if (HeaderByteCount > ( 4 * Kumu::Megabyte ) )
+ {
+ DefaultLogSink().Warn("Improbably huge HeaderByteCount value: %qu\n", HeaderByteCount);
+ }
+
+ result = m_HeaderData.Capacity(Kumu::xmin(4*Kumu::Megabyte, static_cast<ui32_t>(HeaderByteCount)));
if ( ASDCP_SUCCESS(result) )
{
@@ -1219,6 +1224,13 @@ ASDCP::MXF::OPAtomIndexFooter::Lookup(ui32_t frame_num, IndexTableSegment::Index
//
void
+ASDCP::MXF::OPAtomIndexFooter::SetDeltaParams(const IndexTableSegment::DeltaEntry& delta)
+{
+ m_DefaultDeltaEntry = delta;
+}
+
+//
+void
ASDCP::MXF::OPAtomIndexFooter::SetIndexParamsCBR(IPrimerLookup* lookup, ui32_t size, const Rational& Rate)
{
assert(lookup);
@@ -1259,7 +1271,7 @@ ASDCP::MXF::OPAtomIndexFooter::PushIndexEntry(const IndexTableSegment::IndexEntr
m_CurrentSegment = new IndexTableSegment(m_Dict);
assert(m_CurrentSegment);
AddChildObject(m_CurrentSegment);
- m_CurrentSegment->DeltaEntryArray.push_back(IndexTableSegment::DeltaEntry());
+ m_CurrentSegment->DeltaEntryArray.push_back(m_DefaultDeltaEntry);
m_CurrentSegment->IndexEditRate = m_EditRate;
m_CurrentSegment->IndexStartPosition = 0;
}
@@ -1271,7 +1283,7 @@ ASDCP::MXF::OPAtomIndexFooter::PushIndexEntry(const IndexTableSegment::IndexEntr
m_CurrentSegment = new IndexTableSegment(m_Dict);
assert(m_CurrentSegment);
AddChildObject(m_CurrentSegment);
- m_CurrentSegment->DeltaEntryArray.push_back(IndexTableSegment::DeltaEntry());
+ m_CurrentSegment->DeltaEntryArray.push_back(m_DefaultDeltaEntry);
m_CurrentSegment->IndexEditRate = m_EditRate;
m_CurrentSegment->IndexStartPosition = StartPosition;
}
@@ -1427,7 +1439,7 @@ static bool s_TypesInit = false;
//
void
-ASDCP::MXF::SetObjectFactory(ASDCP::UL label, ASDCP::MXF::MXFObjectFactory_t factory)
+ASDCP::MXF::SetObjectFactory(const ASDCP::UL& label, ASDCP::MXF::MXFObjectFactory_t factory)
{
s_FactoryList.Insert(label, factory);
}
@@ -1460,10 +1472,9 @@ ASDCP::MXF::CreateObject(const Dictionary*& Dict, const UL& label)
//
bool
-ASDCP::MXF::decode_mca_string(const std::string& s, const mca_label_map_t& labels, const Dictionary& dict, const std::string& language,
+ASDCP::MXF::decode_mca_string(const std::string& s, const mca_label_map_t& labels, const Dictionary*& dict, const std::string& language,
InterchangeObject_list_t& descriptor_list, ui32_t& channel_count)
{
- const Dictionary *dictp = &dict;
std::string symbol_buf;
channel_count = 0;
ASDCP::MXF::SoundfieldGroupLabelSubDescriptor *current_soundfield = 0;
@@ -1475,13 +1486,13 @@ ASDCP::MXF::decode_mca_string(const std::string& s, const mca_label_map_t& label
{
if ( current_soundfield != 0 )
{
- fprintf(stderr, "Encountered '(', already processing a soundfield group.\n");
+ DefaultLogSink().Error("Encountered '(', already processing a soundfield group.\n");
return false;
}
if ( symbol_buf.empty() )
{
- fprintf(stderr, "Encountered '(', without leading soundfield group symbol.\n");
+ DefaultLogSink().Error("Encountered '(', without leading soundfield group symbol.\n");
return false;
}
@@ -1489,17 +1500,17 @@ ASDCP::MXF::decode_mca_string(const std::string& s, const mca_label_map_t& label
if ( i == labels.end() )
{
- fprintf(stderr, "Unknown symbol: '%s'\n", symbol_buf.c_str());
+ DefaultLogSink().Error("Unknown symbol: '%s'\n", symbol_buf.c_str());
return false;
}
if ( i->second.Value()[10] != 2 ) // magic depends on UL "Essence Facet" byte (see ST 428-12)
{
- fprintf(stderr, "Not a soundfield group symbol: '%s'\n", symbol_buf.c_str());
+ DefaultLogSink().Error("Not a soundfield group symbol: '%s'\n", symbol_buf.c_str());
return false;
}
- current_soundfield = new ASDCP::MXF::SoundfieldGroupLabelSubDescriptor(dictp);
+ current_soundfield = new ASDCP::MXF::SoundfieldGroupLabelSubDescriptor(dict);
GenRandomValue(current_soundfield->InstanceUID);
GenRandomValue(current_soundfield->MCALinkID);
@@ -1514,13 +1525,13 @@ ASDCP::MXF::decode_mca_string(const std::string& s, const mca_label_map_t& label
{
if ( current_soundfield == 0 )
{
- fprintf(stderr, "Encountered ')', not currently processing a soundfield group.\n");
+ DefaultLogSink().Error("Encountered ')', not currently processing a soundfield group.\n");
return false;
}
if ( symbol_buf.empty() )
{
- fprintf(stderr, "Soundfield group description contains no channels.\n");
+ DefaultLogSink().Error("Soundfield group description contains no channels.\n");
return false;
}
@@ -1528,16 +1539,16 @@ ASDCP::MXF::decode_mca_string(const std::string& s, const mca_label_map_t& label
if ( i == labels.end() )
{
- fprintf(stderr, "Unknown symbol: '%s'\n", symbol_buf.c_str());
+ DefaultLogSink().Error("Unknown symbol: '%s'\n", symbol_buf.c_str());
return false;
}
ASDCP::MXF::AudioChannelLabelSubDescriptor *channel_descr =
- new ASDCP::MXF::AudioChannelLabelSubDescriptor(dictp);
+ new ASDCP::MXF::AudioChannelLabelSubDescriptor(dict);
GenRandomValue(channel_descr->InstanceUID);
assert(current_soundfield);
- channel_descr->MCALinkID = current_soundfield->MCALinkID;
+ channel_descr->SoundfieldGroupLinkID = current_soundfield->MCALinkID;
channel_descr->MCAChannelID = channel_count++;
channel_descr->MCATagSymbol = "ch" + i->first;
channel_descr->MCATagName = i->first;
@@ -1555,24 +1566,24 @@ ASDCP::MXF::decode_mca_string(const std::string& s, const mca_label_map_t& label
if ( i == labels.end() )
{
- fprintf(stderr, "Unknown symbol: '%s'\n", symbol_buf.c_str());
+ DefaultLogSink().Error("Unknown symbol: '%s'\n", symbol_buf.c_str());
return false;
}
if ( i->second.Value()[10] != 1 ) // magic depends on UL "Essence Facet" byte (see ST 428-12)
{
- fprintf(stderr, "Not a channel symbol: '%s'\n", symbol_buf.c_str());
+ DefaultLogSink().Error("Not a channel symbol: '%s'\n", symbol_buf.c_str());
return false;
}
ASDCP::MXF::AudioChannelLabelSubDescriptor *channel_descr =
- new ASDCP::MXF::AudioChannelLabelSubDescriptor(dictp);
+ new ASDCP::MXF::AudioChannelLabelSubDescriptor(dict);
GenRandomValue(channel_descr->InstanceUID);
if ( current_soundfield != 0 )
{
- channel_descr->MCALinkID = current_soundfield->MCALinkID;
+ channel_descr->SoundfieldGroupLinkID = current_soundfield->MCALinkID;
}
channel_descr->MCAChannelID = channel_count++;
@@ -1590,7 +1601,7 @@ ASDCP::MXF::decode_mca_string(const std::string& s, const mca_label_map_t& label
}
else if ( ! isspace(*i) )
{
- fprintf(stderr, "Unexpected character '%c'.\n", *i);
+ DefaultLogSink().Error("Unexpected character '%c'.\n", *i);
return false;
}
}
@@ -1601,18 +1612,18 @@ ASDCP::MXF::decode_mca_string(const std::string& s, const mca_label_map_t& label
if ( i == labels.end() )
{
- fprintf(stderr, "Unknown symbol: '%s'\n", symbol_buf.c_str());
+ DefaultLogSink().Error("Unknown symbol: '%s'\n", symbol_buf.c_str());
return false;
}
ASDCP::MXF::AudioChannelLabelSubDescriptor *channel_descr =
- new ASDCP::MXF::AudioChannelLabelSubDescriptor(dictp);
+ new ASDCP::MXF::AudioChannelLabelSubDescriptor(dict);
GenRandomValue(channel_descr->InstanceUID);
if ( current_soundfield != 0 )
{
- channel_descr->MCALinkID = current_soundfield->MCALinkID;
+ channel_descr->SoundfieldGroupLinkID = current_soundfield->MCALinkID;
}
channel_descr->MCAChannelID = channel_count++;
@@ -1626,7 +1637,7 @@ ASDCP::MXF::decode_mca_string(const std::string& s, const mca_label_map_t& label
return true;
}
-
+//
ASDCP::MXF::ASDCP_MCAConfigParser::ASDCP_MCAConfigParser(const Dictionary*& d) : m_Dict(d), m_ChannelCount(0)
{
m_LabelMap.insert(mca_label_map_t::value_type("L", m_Dict->ul(MDD_DCAudioChannel_L)));
@@ -1662,7 +1673,7 @@ ASDCP::MXF::ASDCP_MCAConfigParser::ChannelCount() const
bool
ASDCP::MXF::ASDCP_MCAConfigParser::DecodeString(const std::string& s, const std::string& language)
{
- return decode_mca_string(s, m_LabelMap, *m_Dict, language, *this, m_ChannelCount);
+ return decode_mca_string(s, m_LabelMap, m_Dict, language, *this, m_ChannelCount);
}
diff --git a/src/MXF.h b/src/MXF.h
index 4af8993..6e6a47a 100755
--- a/src/MXF.h
+++ b/src/MXF.h
@@ -47,7 +47,7 @@ namespace ASDCP
typedef ASDCP::MXF::InterchangeObject* (*MXFObjectFactory_t)(const Dictionary*&);
//
- void SetObjectFactory(UL label, MXFObjectFactory_t factory);
+ void SetObjectFactory(const UL& label, MXFObjectFactory_t factory);
//
InterchangeObject* CreateObject(const Dictionary*& Dict, const UL& label);
@@ -303,6 +303,7 @@ namespace ASDCP
//
class IndexTableSegment : public InterchangeObject
{
+ IndexTableSegment();
ASDCP_NO_COPY_CONSTRUCT(IndexTableSegment);
public:
@@ -314,7 +315,7 @@ namespace ASDCP
ui8_t Slice;
ui32_t ElementData;
- DeltaEntry() : PosTableIndex(-1), Slice(0), ElementData(0) {}
+ DeltaEntry() : PosTableIndex(0), Slice(0), ElementData(0) {}
DeltaEntry(i8_t pos, ui8_t slice, ui32_t data) : PosTableIndex(pos), Slice(slice), ElementData(data) {}
inline bool HasValue() const { return true; }
ui32_t ArchiveLength() const { return sizeof(ui32_t) + 2; }
@@ -412,6 +413,7 @@ namespace ASDCP
ui32_t m_BytesPerEditUnit;
Rational m_EditRate;
ui32_t m_BodySID;
+ IndexTableSegment::DeltaEntry m_DefaultDeltaEntry;
ASDCP_NO_COPY_CONSTRUCT(OPAtomIndexFooter);
OPAtomIndexFooter();
@@ -435,6 +437,7 @@ namespace ASDCP
virtual Result_t Lookup(ui32_t frame_num, IndexTableSegment::IndexEntry&) const;
virtual void PushIndexEntry(const IndexTableSegment::IndexEntry&);
+ virtual void SetDeltaParams(const IndexTableSegment::DeltaEntry&);
virtual void SetIndexParamsCBR(IPrimerLookup* lookup, ui32_t size, const Rational& Rate);
virtual void SetIndexParamsVBR(IPrimerLookup* lookup, const Rational& Rate, Kumu::fpos_t offset);
};
@@ -457,7 +460,8 @@ namespace ASDCP
};
typedef std::map<const std::string, const UL, ci_comp> mca_label_map_t;
- bool decode_mca_string(const std::string& s, const mca_label_map_t& labels, const Dictionary& dict, const std::string& language, InterchangeObject_list_t&, ui32_t&);
+ bool decode_mca_string(const std::string& s, const mca_label_map_t& labels,
+ const Dictionary*& dict, const std::string& language, InterchangeObject_list_t&, ui32_t&);
//
class ASDCP_MCAConfigParser : public InterchangeObject_list_t
diff --git a/src/Makefile.am b/src/Makefile.am
index c1bcf00..83f8597 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -129,9 +129,9 @@ libas02_la_SOURCES = \
h__02_Reader.cpp \
h__02_Writer.cpp \
ST2052_TextParser.cpp \
- AS_02_TimedText.cpp \
AS_02_JP2K.cpp \
- AS_02_PCM.cpp
+ AS_02_PCM.cpp \
+ AS_02_TimedText.cpp
libas02_la_LDFLAGS = -release @VERSION@
libas02_la_LIBADD = libasdcp.la libkumu.la
@@ -161,6 +161,10 @@ libpyasdcp_la_CPPFLAGS = @PYTHON_CPPFLAGS@
libpyasdcp_la_LDFLAGS = @PYTHON_LSPEC@ -release @VERSION@
libpyasdcp_la_LIBADD = libkumu.la libasdcp.la
+if USE_AS_02
+libpyasdcp_la_LIBADD += libas02.la
+endif
+
pyexecdir = @PYTHON_EXECDIR@
pyexec_includedir = $(PYTHON_PREFIX)/include/python$(PYTHON_SHORTVERSION)
nodist_pyexec_include_HEADERS = kumu_python.h asdcp_python.h asdcp_wrappers.h
diff --git a/src/PCMParserList.cpp b/src/PCMParserList.cpp
index 2ebdfa0..8b81619 100755
--- a/src/PCMParserList.cpp
+++ b/src/PCMParserList.cpp
@@ -1,5 +1,5 @@
/*
-Copyright (c) 2004-2012, John Hurst
+Copyright (c) 2004-2013, John Hurst
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -48,10 +48,8 @@ ASDCP::ParserInstance::~ParserInstance()
// PCM::CalcSampleSize(ADesc);
Result_t
-ASDCP::ParserInstance::OpenRead(const char* filename, const Rational& PictureRate)
+ASDCP::ParserInstance::OpenRead(const std::string& filename, const Rational& PictureRate)
{
- ASDCP_TEST_NULL_STR(filename);
-
Result_t result = Parser.OpenRead(filename, PictureRate);
if ( ASDCP_SUCCESS(result) )
diff --git a/src/PCMParserList.h b/src/PCMParserList.h
index 80c1d52..dbacd68 100755
--- a/src/PCMParserList.h
+++ b/src/PCMParserList.h
@@ -1,5 +1,5 @@
/*
-Copyright (c) 2004-2012, John Hurst
+Copyright (c) 2004-2013, John Hurst
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -54,7 +54,7 @@ namespace ASDCP
ParserInstance();
virtual ~ParserInstance();
- Result_t OpenRead(const char* filename, const Rational& PictureRate);
+ Result_t OpenRead(const std::string& filename, const Rational& PictureRate);
Result_t PutSample(byte_t* p);
Result_t ReadFrame();
inline ui32_t SampleSize() { return m_SampleSize; }
diff --git a/src/PCM_Parser.cpp b/src/PCM_Parser.cpp
index e3b693d..30e5d28 100755
--- a/src/PCM_Parser.cpp
+++ b/src/PCM_Parser.cpp
@@ -69,7 +69,7 @@ public:
Close();
}
- Result_t OpenRead(const char* filename, const Rational& PictureRate);
+ Result_t OpenRead(const std::string& filename, const Rational& PictureRate);
void Close();
void Reset();
Result_t ReadFrame(FrameBuffer&);
@@ -94,10 +94,8 @@ ASDCP::PCM::WAVParser::h__WAVParser::Reset()
//
ASDCP::Result_t
-ASDCP::PCM::WAVParser::h__WAVParser::OpenRead(const char* filename, const Rational& PictureRate)
+ASDCP::PCM::WAVParser::h__WAVParser::OpenRead(const std::string& filename, const Rational& PictureRate)
{
- ASDCP_TEST_NULL_STR(filename);
-
Result_t result = m_FileReader.OpenRead(filename);
if ( ASDCP_SUCCESS(result) )
@@ -203,7 +201,7 @@ ASDCP::PCM::WAVParser::~WAVParser()
// Opens the stream for reading, parses enough data to provide a complete
// set of stream metadata for the MXFWriter below.
ASDCP::Result_t
-ASDCP::PCM::WAVParser::OpenRead(const char* filename, const Rational& PictureRate) const
+ASDCP::PCM::WAVParser::OpenRead(const std::string& filename, const Rational& PictureRate) const
{
const_cast<ASDCP::PCM::WAVParser*>(this)->m_Parser = new h__WAVParser;
diff --git a/src/TimedText_Parser.cpp b/src/TimedText_Parser.cpp
index b7b58c5..3312b58 100644
--- a/src/TimedText_Parser.cpp
+++ b/src/TimedText_Parser.cpp
@@ -136,8 +136,8 @@ public:
return m_DefaultResolver;
}
- Result_t OpenRead(const char* filename);
- Result_t OpenRead(const std::string& xml_doc, const char* filename);
+ Result_t OpenRead(const std::string& filename);
+ Result_t OpenRead(const std::string& xml_doc, const std::string& filename);
Result_t ReadAncillaryResource(const byte_t* uuid, FrameBuffer& FrameBuf, const IResourceResolver& Resolver) const;
};
@@ -178,7 +178,7 @@ decode_rational(const char* str_rat)
//
Result_t
-ASDCP::TimedText::DCSubtitleParser::h__SubtitleParser::OpenRead(const char* filename)
+ASDCP::TimedText::DCSubtitleParser::h__SubtitleParser::OpenRead(const std::string& filename)
{
Result_t result = ReadFileIntoString(filename, m_XMLDoc);
@@ -191,14 +191,18 @@ ASDCP::TimedText::DCSubtitleParser::h__SubtitleParser::OpenRead(const char* file
//
Result_t
-ASDCP::TimedText::DCSubtitleParser::h__SubtitleParser::OpenRead(const std::string& xml_doc, const char* filename)
+ASDCP::TimedText::DCSubtitleParser::h__SubtitleParser::OpenRead(const std::string& xml_doc, const std::string& filename)
{
m_XMLDoc = xml_doc;
- if ( filename != 0 )
- m_Filename = filename;
+ if ( filename.empty() )
+ {
+ m_Filename = "<string>";
+ }
else
- m_Filename = "<string>";
+ {
+ m_Filename = filename;
+ }
return OpenRead();
}
@@ -394,7 +398,7 @@ ASDCP::TimedText::DCSubtitleParser::~DCSubtitleParser()
// Opens the stream for reading, parses enough data to provide a complete
// set of stream metadata for the MXFWriter below.
ASDCP::Result_t
-ASDCP::TimedText::DCSubtitleParser::OpenRead(const char* filename) const
+ASDCP::TimedText::DCSubtitleParser::OpenRead(const std::string& filename) const
{
const_cast<ASDCP::TimedText::DCSubtitleParser*>(this)->m_Parser = new h__SubtitleParser;
@@ -408,7 +412,7 @@ ASDCP::TimedText::DCSubtitleParser::OpenRead(const char* filename) const
// Parses an XML document to provide a complete set of stream metadata for the MXFWriter below.
Result_t
-ASDCP::TimedText::DCSubtitleParser::OpenRead(const std::string& xml_doc, const char* filename) const
+ASDCP::TimedText::DCSubtitleParser::OpenRead(const std::string& xml_doc, const std::string& filename) const
{
const_cast<ASDCP::TimedText::DCSubtitleParser*>(this)->m_Parser = new h__SubtitleParser;
diff --git a/src/as-02-unwrap.cpp b/src/as-02-unwrap.cpp
index b85781d..ae66df7 100755
--- a/src/as-02-unwrap.cpp
+++ b/src/as-02-unwrap.cpp
@@ -1,5 +1,5 @@
/*
-Copyright (c) 2011-2012, Robert Scheler, Heiko Sparenberg Fraunhofer IIS,
+Copyright (c) 2011-2013, Robert Scheler, Heiko Sparenberg Fraunhofer IIS,
John Hurst
All rights reserved.
@@ -420,44 +420,51 @@ read_PCM_file(CommandOptions& Options)
Result_t result = Reader.OpenRead(Options.input_filename, Options.edit_rate);
- if ( ASDCP_SUCCESS(result) )
+ if ( KM_SUCCESS(result) )
{
if ( Options.verbose_flag )
{
fprintf(stderr, "Frame Buffer size: %u\n", Options.fb_size);
}
+
+ ASDCP::MXF::InterchangeObject* tmp_obj = 0;
- result = Reader.OP1aHeader().GetMDObjectByType(DefaultCompositeDict().ul(MDD_WaveAudioDescriptor),
- reinterpret_cast<MXF::InterchangeObject**>(&wave_descriptor));
+ result = Reader.OP1aHeader().GetMDObjectByType(DefaultCompositeDict().ul(MDD_WaveAudioDescriptor), &tmp_obj);
if ( KM_SUCCESS(result) )
{
- assert(wave_descriptor);
- last_frame = wave_descriptor->ContainerDuration;
+ wave_descriptor = dynamic_cast<ASDCP::MXF::WaveAudioDescriptor*>(tmp_obj);
+ if ( wave_descriptor == 0 )
+ {
+ fprintf(stderr, "File does not contain an essence descriptor.\n");
+ return RESULT_FAIL;
+ }
+
if ( Options.verbose_flag )
{
wave_descriptor->Dump();
}
- }
- else
- {
- fprintf(stderr, "File does not contain an essence descriptor.\n");
- last_frame = Reader.AS02IndexReader().GetDuration();
- }
- if ( last_frame == 0 )
- {
- fprintf(stderr, "Unable to determine file duration.\n");
- return RESULT_FAIL;
- }
+ if ( wave_descriptor->ContainerDuration.get() == 0 )
+ {
+ fprintf(stderr, "ContainerDuration not set in file descriptor, attempting to use index duration.\n");
+ last_frame = Reader.AS02IndexReader().GetDuration();
+ }
+ else
+ {
+ last_frame = wave_descriptor->ContainerDuration;
+ }
- FrameBuffer.Capacity(AS_02::MXF::CalcFrameBufferSize(*wave_descriptor, Options.edit_rate));
- last_frame = AS_02::MXF::CalcFramesFromDurationInSamples(last_frame, *wave_descriptor, Options.edit_rate);
+ if ( last_frame == 0 )
+ {
+ fprintf(stderr, "Unable to determine file duration.\n");
+ return RESULT_FAIL;
+ }
- if ( Options.verbose_flag )
- {
- wave_descriptor->Dump();
+ assert(wave_descriptor);
+ FrameBuffer.Capacity(AS_02::MXF::CalcFrameBufferSize(*wave_descriptor, Options.edit_rate));
+ last_frame = AS_02::MXF::CalcFramesFromDurationInSamples(last_frame, *wave_descriptor, Options.edit_rate);
}
}
@@ -565,12 +572,12 @@ main(int argc, const char** argv)
{
switch ( EssenceType )
{
- case ESS_JPEG_2000:
+ case ESS_AS02_JPEG_2000:
result = read_JP2K_file(Options);
break;
- case ESS_PCM_24b_48k:
- case ESS_PCM_24b_96k:
+ case ESS_AS02_PCM_24b_48k:
+ case ESS_AS02_PCM_24b_96k:
result = read_PCM_file(Options);
break;
@@ -584,11 +591,7 @@ main(int argc, const char** argv)
{
fputs("Program stopped on error.\n", stderr);
- if ( result == RESULT_SFORMAT )
- {
- fputs("Use option '-3' to force stereoscopic mode.\n", stderr);
- }
- else if ( result != RESULT_FAIL )
+ if ( result != RESULT_FAIL )
{
fputs(result, stderr);
fputc('\n', stderr);
diff --git a/src/asdcp-test.cpp b/src/asdcp-test.cpp
index 24d6b1e..a35770a 100755
--- a/src/asdcp-test.cpp
+++ b/src/asdcp-test.cpp
@@ -241,6 +241,9 @@ decode_channel_fmt(const std::string& label_name)
else if ( label_name == "7.1DS" )
return PCM::CF_CFG_5;
+ else if ( label_name == "MCA" )
+ return PCM::CF_CFG_6;
+
fprintf(stderr, "Error decoding channel format string: %s\n", label_name.c_str());
fprintf(stderr, "Expecting '5.1', '6.1', '7.1', '7.1DS' or 'WTF'\n");
return PCM::CF_NONE;
diff --git a/src/asdcp-wrap.cpp b/src/asdcp-wrap.cpp
index 3bad03e..fd4a6d9 100755
--- a/src/asdcp-wrap.cpp
+++ b/src/asdcp-wrap.cpp
@@ -187,6 +187,9 @@ decode_channel_fmt(const std::string& label_name)
else if ( label_name == "7.1DS" )
return PCM::CF_CFG_5;
+ else if ( label_name == "MCA" )
+ return PCM::CF_CFG_6;
+
fprintf(stderr, "Error decoding channel format string: %s\n", label_name.c_str());
fprintf(stderr, "Expecting '5.1', '6.1', '7.1', '7.1DS' or 'WTF'\n");
return PCM::CF_NONE;
@@ -475,7 +478,7 @@ write_MPEG2_file(CommandOptions& Options)
Kumu::FortunaRNG RNG;
// set up essence parser
- Result_t result = Parser.OpenRead(Options.filenames.front().c_str());
+ Result_t result = Parser.OpenRead(Options.filenames.front());
// set up MXF writer
if ( ASDCP_SUCCESS(result) )
@@ -531,7 +534,7 @@ write_MPEG2_file(CommandOptions& Options)
}
if ( ASDCP_SUCCESS(result) )
- result = Writer.OpenWrite(Options.out_file.c_str(), Info, VDesc);
+ result = Writer.OpenWrite(Options.out_file, Info, VDesc);
}
if ( ASDCP_SUCCESS(result) )
@@ -631,12 +634,12 @@ write_JP2K_S_file(CommandOptions& Options)
}
// set up essence parser
- Result_t result = ParserLeft.OpenRead(Options.filenames.front().c_str(), Options.j2c_pedantic);
+ Result_t result = ParserLeft.OpenRead(Options.filenames.front(), Options.j2c_pedantic);
if ( ASDCP_SUCCESS(result) )
{
Options.filenames.pop_front();
- result = ParserRight.OpenRead(Options.filenames.front().c_str(), Options.j2c_pedantic);
+ result = ParserRight.OpenRead(Options.filenames.front(), Options.j2c_pedantic);
}
// set up MXF writer
@@ -696,7 +699,7 @@ write_JP2K_S_file(CommandOptions& Options)
}
if ( ASDCP_SUCCESS(result) )
- result = Writer.OpenWrite(Options.out_file.c_str(), Info, PDesc);
+ result = Writer.OpenWrite(Options.out_file, Info, PDesc);
if ( ASDCP_SUCCESS(result) && Options.picture_coding.HasValue() )
{
@@ -771,7 +774,7 @@ write_JP2K_file(CommandOptions& Options)
Kumu::FortunaRNG RNG;
// set up essence parser
- Result_t result = Parser.OpenRead(Options.filenames.front().c_str(), Options.j2c_pedantic);
+ Result_t result = Parser.OpenRead(Options.filenames.front(), Options.j2c_pedantic);
// set up MXF writer
if ( ASDCP_SUCCESS(result) )
@@ -831,7 +834,7 @@ write_JP2K_file(CommandOptions& Options)
}
if ( ASDCP_SUCCESS(result) )
- result = Writer.OpenWrite(Options.out_file.c_str(), Info, PDesc);
+ result = Writer.OpenWrite(Options.out_file, Info, PDesc);
if ( ASDCP_SUCCESS(result) && Options.picture_coding.HasValue() )
{
@@ -915,9 +918,9 @@ write_PCM_file(CommandOptions& Options)
FrameBuffer.Capacity(PCM::CalcFrameBufferSize(ADesc));
ADesc.ChannelFormat = Options.channel_fmt;
- if ( Options.use_smpte_labels && ADesc.ChannelFormat == PCM::CF_NONE)
+ if ( Options.use_smpte_labels && ADesc.ChannelFormat == PCM::CF_NONE && Options.mca_config.empty() )
{
- fprintf(stderr, "ATTENTION! Writing SMPTE audio without ChannelAssignment property (see option -l)\n");
+ fprintf(stderr, "ATTENTION! Writing SMPTE audio without ChannelAssignment property (see options -C, -l and -m)\n");
}
if ( Options.verbose_flag )
@@ -971,7 +974,7 @@ write_PCM_file(CommandOptions& Options)
}
if ( ASDCP_SUCCESS(result) )
- result = Writer.OpenWrite(Options.out_file.c_str(), Info, ADesc);
+ result = Writer.OpenWrite(Options.out_file, Info, ADesc);
if ( ASDCP_SUCCESS(result)
&& ( Options.channel_assignment.HasValue()
@@ -1139,7 +1142,7 @@ write_PCM_with_ATMOS_sync_file(CommandOptions& Options)
}
if ( ASDCP_SUCCESS(result) )
- result = Writer.OpenWrite(Options.out_file.c_str(), Info, ADesc);
+ result = Writer.OpenWrite(Options.out_file, Info, ADesc);
}
if ( ASDCP_SUCCESS(result) )
@@ -1209,7 +1212,7 @@ write_timed_text_file(CommandOptions& Options)
Kumu::FortunaRNG RNG;
// set up essence parser
- Result_t result = Parser.OpenRead(Options.filenames.front().c_str());
+ Result_t result = Parser.OpenRead(Options.filenames.front());
// set up MXF writer
if ( ASDCP_SUCCESS(result) )
@@ -1262,7 +1265,7 @@ write_timed_text_file(CommandOptions& Options)
}
if ( ASDCP_SUCCESS(result) )
- result = Writer.OpenWrite(Options.out_file.c_str(), Info, TDesc);
+ result = Writer.OpenWrite(Options.out_file, Info, TDesc);
}
if ( ASDCP_FAILURE(result) )
@@ -1324,7 +1327,7 @@ write_dolby_atmos_file(CommandOptions& Options)
Kumu::FortunaRNG RNG;
// set up essence parser
- Result_t result = Parser.OpenRead(Options.filenames.front().c_str());
+ Result_t result = Parser.OpenRead(Options.filenames.front());
// set up MXF writer
if ( ASDCP_SUCCESS(result) )
@@ -1382,7 +1385,7 @@ write_dolby_atmos_file(CommandOptions& Options)
}
if ( ASDCP_SUCCESS(result) )
- result = Writer.OpenWrite(Options.out_file.c_str(), Info, ADesc);
+ result = Writer.OpenWrite(Options.out_file, Info, ADesc);
}
if ( ASDCP_SUCCESS(result) )
@@ -1460,7 +1463,7 @@ main(int argc, const char** argv)
}
EssenceType_t EssenceType;
- result = ASDCP::RawEssenceType(Options.filenames.front().c_str(), EssenceType);
+ result = ASDCP::RawEssenceType(Options.filenames.front(), EssenceType);
if ( ASDCP_SUCCESS(result) )
{
diff --git a/src/h__02_Reader.cpp b/src/h__02_Reader.cpp
index 1a0de11..b67f9c8 100644
--- a/src/h__02_Reader.cpp
+++ b/src/h__02_Reader.cpp
@@ -341,10 +341,10 @@ AS_02::MXF::AS02IndexReader::GetDuration() const
Result_t
AS_02::MXF::AS02IndexReader::Lookup(ui32_t frame_num, ASDCP::MXF::IndexTableSegment::IndexEntry& Entry) const
{
- std::list<InterchangeObject*>::iterator li;
- for ( li = m_PacketList->m_List.begin(); li != m_PacketList->m_List.end(); li++ )
+ std::list<InterchangeObject*>::iterator i;
+ for ( i = m_PacketList->m_List.begin(); i != m_PacketList->m_List.end(); ++i )
{
- IndexTableSegment *segment = dynamic_cast<IndexTableSegment*>(*li);
+ IndexTableSegment *segment = dynamic_cast<IndexTableSegment*>(*i);
if ( segment != 0 )
{
@@ -373,6 +373,7 @@ AS_02::MXF::AS02IndexReader::Lookup(ui32_t frame_num, ASDCP::MXF::IndexTableSegm
}
}
+ DefaultLogSink().Error("AS_02::MXF::AS02IndexReader::Lookup FAILED: frame_num=%d\n", frame_num);
return RESULT_FAIL;
}
diff --git a/src/h__02_Writer.cpp b/src/h__02_Writer.cpp
index c81da5c..1de4392 100644
--- a/src/h__02_Writer.cpp
+++ b/src/h__02_Writer.cpp
@@ -42,18 +42,18 @@ static const ui32_t CBRIndexEntriesPerSegment = 5000;
//------------------------------------------------------------------------------------------
//
-AS_02::MXF::AS02IndexWriter::AS02IndexWriter(const ASDCP::Dictionary*& d) :
- Partition(d), m_CurrentSegment(0), m_BytesPerEditUnit(0), m_Dict(d), m_Lookup(0)
+AS_02::MXF::AS02IndexWriterVBR::AS02IndexWriterVBR(const ASDCP::Dictionary*& d) :
+ Partition(d), m_CurrentSegment(0), m_Dict(d), m_Lookup(0)
{
BodySID = 0;
IndexSID = 129;
}
-AS_02::MXF::AS02IndexWriter::~AS02IndexWriter() {}
+AS_02::MXF::AS02IndexWriterVBR::~AS02IndexWriterVBR() {}
//
Result_t
-AS_02::MXF::AS02IndexWriter::WriteToFile(Kumu::FileWriter& Writer)
+AS_02::MXF::AS02IndexWriterVBR::WriteToFile(Kumu::FileWriter& Writer)
{
assert(m_Dict);
ASDCP::FrameBuffer index_body_buffer;
@@ -114,7 +114,7 @@ AS_02::MXF::AS02IndexWriter::WriteToFile(Kumu::FileWriter& Writer)
//
void
-AS_02::MXF::AS02IndexWriter::Dump(FILE* stream)
+AS_02::MXF::AS02IndexWriterVBR::Dump(FILE* stream)
{
if ( stream == 0 )
stream = stderr;
@@ -130,7 +130,7 @@ AS_02::MXF::AS02IndexWriter::Dump(FILE* stream)
//
ui32_t
-AS_02::MXF::AS02IndexWriter::GetDuration() const
+AS_02::MXF::AS02IndexWriterVBR::GetDuration() const
{
ui32_t duration = 0;
std::list<InterchangeObject*>::const_iterator i;
@@ -149,39 +149,8 @@ AS_02::MXF::AS02IndexWriter::GetDuration() const
//
void
-AS_02::MXF::AS02IndexWriter::SetIndexParamsCBR(IPrimerLookup* lookup, ui32_t size, const ASDCP::Rational& Rate)
+AS_02::MXF::AS02IndexWriterVBR::PushIndexEntry(const IndexTableSegment::IndexEntry& Entry)
{
- assert(lookup);
- m_Lookup = lookup;
- m_BytesPerEditUnit = size;
- m_EditRate = Rate;
-
- IndexTableSegment* Index = new IndexTableSegment(m_Dict);
- AddChildObject(Index);
- Index->EditUnitByteCount = m_BytesPerEditUnit;
- Index->IndexEditRate = Rate;
-}
-
-//
-void
-AS_02::MXF::AS02IndexWriter::SetIndexParamsVBR(IPrimerLookup* lookup, const ASDCP::Rational& Rate, Kumu::fpos_t offset)
-{
- assert(lookup);
- m_Lookup = lookup;
- m_BytesPerEditUnit = 0;
- m_EditRate = Rate;
-}
-
-//
-void
-AS_02::MXF::AS02IndexWriter::PushIndexEntry(const IndexTableSegment::IndexEntry& Entry)
-{
- if ( m_BytesPerEditUnit != 0 ) // are we CBR? that's bad
- {
- DefaultLogSink().Error("Call to PushIndexEntry() failed: index is CBR\n");
- return;
- }
-
// do we have an available segment?
if ( m_CurrentSegment == 0 )
{ // no, set up a new segment
@@ -192,19 +161,6 @@ AS_02::MXF::AS02IndexWriter::PushIndexEntry(const IndexTableSegment::IndexEntry&
m_CurrentSegment->IndexEditRate = m_EditRate;
m_CurrentSegment->IndexStartPosition = 0;
}
- else if ( m_CurrentSegment->IndexEntryArray.size() >= CBRIndexEntriesPerSegment )
- { // no, this one is full, start another
- DefaultLogSink().Warn("%s, line %d: This has never been tested.\n", __FILE__, __LINE__);
- m_CurrentSegment->IndexDuration = m_CurrentSegment->IndexEntryArray.size();
- ui64_t start_position = m_CurrentSegment->IndexStartPosition + m_CurrentSegment->IndexDuration;
-
- m_CurrentSegment = new IndexTableSegment(m_Dict);
- assert(m_CurrentSegment);
- AddChildObject(m_CurrentSegment);
- m_CurrentSegment->DeltaEntryArray.push_back(IndexTableSegment::DeltaEntry());
- m_CurrentSegment->IndexEditRate = m_EditRate;
- m_CurrentSegment->IndexStartPosition = start_position;
- }
m_CurrentSegment->IndexEntryArray.push_back(Entry);
}
@@ -214,65 +170,14 @@ AS_02::MXF::AS02IndexWriter::PushIndexEntry(const IndexTableSegment::IndexEntry&
//
//
-AS_02::h__AS02Writer::h__AS02Writer(const ASDCP::Dictionary& d) : ASDCP::MXF::TrackFileWriter<ASDCP::MXF::OP1aHeader>(d),
- m_ECStart(0), m_ClipStart(0), m_IndexWriter(m_Dict), m_PartitionSpace(0),
- m_IndexStrategy(AS_02::IS_FOLLOW) {}
+AS_02::h__AS02WriterFrame::h__AS02WriterFrame(const ASDCP::Dictionary& d) :
+ h__AS02Writer<AS_02::MXF::AS02IndexWriterVBR>(d), m_IndexStrategy(AS_02::IS_FOLLOW) {}
-AS_02::h__AS02Writer::~h__AS02Writer() {}
+AS_02::h__AS02WriterFrame::~h__AS02WriterFrame() {}
//
Result_t
-AS_02::h__AS02Writer::WriteAS02Header(const std::string& PackageLabel, const ASDCP::UL& WrappingUL,
- const std::string& TrackName, const ASDCP::UL& EssenceUL, const ASDCP::UL& DataDefinition,
- const ASDCP::Rational& EditRate, ui32_t TCFrameRate, ui32_t BytesPerEditUnit)
-{
- if ( EditRate.Numerator == 0 || EditRate.Denominator == 0 )
- {
- DefaultLogSink().Error("Non-zero edit-rate reqired.\n");
- return RESULT_PARAM;
- }
-
- InitHeader();
-
- AddSourceClip(EditRate, EditRate/*TODO: for a moment*/, TCFrameRate, TrackName, EssenceUL, DataDefinition, PackageLabel);
- AddEssenceDescriptor(WrappingUL);
- m_RIP.PairArray.push_back(RIP::Pair(0, 0)); // Header partition RIP entry
- m_IndexWriter.OperationalPattern = m_HeaderPart.OperationalPattern;
- m_IndexWriter.EssenceContainers = m_HeaderPart.EssenceContainers;
-
- Result_t result = m_HeaderPart.WriteToFile(m_File, m_HeaderSize);
-
- if ( ASDCP_SUCCESS(result) )
- {
- m_PartitionSpace *= ceil(EditRate.Quotient()); // convert seconds to edit units
- m_ECStart = m_File.Tell();
- m_IndexWriter.IndexSID = 129;
-
- if ( BytesPerEditUnit == 0 )
- {
- m_IndexWriter.SetIndexParamsVBR(&m_HeaderPart.m_Primer, EditRate, m_ECStart);
- }
- else
- {
- m_IndexWriter.SetIndexParamsCBR(&m_HeaderPart.m_Primer, BytesPerEditUnit, EditRate);
- }
-
- UL body_ul(m_Dict->ul(MDD_ClosedCompleteBodyPartition));
- Partition body_part(m_Dict);
- body_part.BodySID = 1;
- body_part.OperationalPattern = m_HeaderPart.OperationalPattern;
- body_part.EssenceContainers = m_HeaderPart.EssenceContainers;
- body_part.ThisPartition = m_ECStart;
- result = body_part.WriteToFile(m_File, body_ul);
- m_RIP.PairArray.push_back(RIP::Pair(1, body_part.ThisPartition)); // Second RIP Entry
- }
-
- return result;
-}
-
-//
-Result_t
-AS_02::h__AS02Writer::WriteEKLVPacket(const ASDCP::FrameBuffer& FrameBuf,const byte_t* EssenceUL, AESEncContext* Ctx, HMACContext* HMAC)
+AS_02::h__AS02WriterFrame::WriteEKLVPacket(const ASDCP::FrameBuffer& FrameBuf,const byte_t* EssenceUL, AESEncContext* Ctx, HMACContext* HMAC)
{
ui64_t this_stream_offset = m_StreamOffset; // m_StreamOffset will be changed by the call to Write_EKLV_Packet
@@ -307,16 +212,101 @@ AS_02::h__AS02Writer::WriteEKLVPacket(const ASDCP::FrameBuffer& FrameBuf,const b
return result;
}
+
+//------------------------------------------------------------------------------------------
+//
+
+
+AS_02::MXF::AS02IndexWriterCBR::AS02IndexWriterCBR(const ASDCP::Dictionary*& d) :
+ Partition(d), m_CurrentSegment(0), m_Dict(d), m_Lookup(0), m_Duration(0), m_SampleSize(0)
+{
+ BodySID = 0;
+ IndexSID = 129;
+}
+
+AS_02::MXF::AS02IndexWriterCBR::~AS02IndexWriterCBR() {}
+
+//
+Result_t
+AS_02::MXF::AS02IndexWriterCBR::WriteToFile(Kumu::FileWriter& Writer)
+{
+ assert(m_Dict);
+ ASDCP::FrameBuffer index_body_buffer;
+ ui32_t index_body_size = MaxIndexSegmentSize; // segment-count * max-segment-size
+ Result_t result = index_body_buffer.Capacity(index_body_size);
+
+ m_CurrentSegment = new IndexTableSegment(m_Dict);
+ assert(m_CurrentSegment);
+ m_CurrentSegment->m_Lookup = m_Lookup;
+ m_CurrentSegment->IndexEditRate = m_EditRate;
+ m_CurrentSegment->IndexStartPosition = 0;
+ m_CurrentSegment->IndexDuration = m_Duration;
+ m_CurrentSegment->EditUnitByteCount = m_SampleSize;
+ AddChildObject(m_CurrentSegment);
+
+ ASDCP::FrameBuffer WriteWrapper;
+ WriteWrapper.SetData(index_body_buffer.Data() + index_body_buffer.Size(),
+ index_body_buffer.Capacity() - index_body_buffer.Size());
+
+ result = m_CurrentSegment->WriteToBuffer(WriteWrapper);
+ index_body_buffer.Size(index_body_buffer.Size() + WriteWrapper.Size());
+ delete m_CurrentSegment;
+ m_CurrentSegment = 0;
+ m_PacketList->m_List.clear();
+
+ if ( KM_SUCCESS(result) )
+ {
+ IndexByteCount = index_body_buffer.Size();
+ UL body_ul(m_Dict->ul(MDD_ClosedCompleteBodyPartition));
+ result = Partition::WriteToFile(Writer, body_ul);
+ }
+
+ if ( KM_SUCCESS(result) )
+ {
+ ui32_t write_count = 0;
+ result = Writer.Write(index_body_buffer.RoData(), index_body_buffer.Size(), &write_count);
+ assert(write_count == index_body_buffer.Size());
+ }
+
+ return result;
+}
+
+//
+ui32_t
+AS_02::MXF::AS02IndexWriterCBR::GetDuration() const
+{
+ return m_Duration;
+}
+
+//
+void
+AS_02::MXF::AS02IndexWriterCBR::SetEditRate(const ASDCP::Rational& edit_rate, const ui32_t& sample_size)
+{
+ m_EditRate = edit_rate;
+ m_SampleSize = sample_size;
+}
+
+
+//------------------------------------------------------------------------------------------
+//
+
+//
+AS_02::h__AS02WriterClip::h__AS02WriterClip(const ASDCP::Dictionary& d) :
+ h__AS02Writer<AS_02::MXF::AS02IndexWriterCBR>(d),
+ m_ECStart(0), m_ClipStart(0), m_IndexStrategy(AS_02::IS_FOLLOW) {}
+
+AS_02::h__AS02WriterClip::~h__AS02WriterClip() {}
+
//
bool
-AS_02::h__AS02Writer::HasOpenClip() const
+AS_02::h__AS02WriterClip::HasOpenClip() const
{
return m_ClipStart != 0;
}
//
Result_t
-AS_02::h__AS02Writer::StartClip(const byte_t* EssenceUL, AESEncContext* Ctx, HMACContext* HMAC)
+AS_02::h__AS02WriterClip::StartClip(const byte_t* EssenceUL, AESEncContext* Ctx, HMACContext* HMAC)
{
if ( Ctx != 0 )
{
@@ -340,7 +330,7 @@ AS_02::h__AS02Writer::StartClip(const byte_t* EssenceUL, AESEncContext* Ctx, HMA
//
Result_t
-AS_02::h__AS02Writer::WriteClipBlock(const ASDCP::FrameBuffer& FrameBuf)
+AS_02::h__AS02WriterClip::WriteClipBlock(const ASDCP::FrameBuffer& FrameBuf)
{
if ( m_ClipStart == 0 )
{
@@ -353,7 +343,7 @@ AS_02::h__AS02Writer::WriteClipBlock(const ASDCP::FrameBuffer& FrameBuf)
//
Result_t
-AS_02::h__AS02Writer::FinalizeClip(ui32_t bytes_per_frame)
+AS_02::h__AS02WriterClip::FinalizeClip(ui32_t bytes_per_frame)
{
if ( m_ClipStart == 0 )
{
@@ -377,86 +367,7 @@ AS_02::h__AS02Writer::FinalizeClip(ui32_t bytes_per_frame)
return result;
}
-// standard method of writing the header and footer of a completed AS-02 file
-//
-Result_t
-AS_02::h__AS02Writer::WriteAS02Footer()
-{
- if ( m_IndexWriter.GetDuration() > 0 )
- {
- m_IndexWriter.ThisPartition = m_File.Tell();
- m_IndexWriter.WriteToFile(m_File);
- m_RIP.PairArray.push_back(RIP::Pair(0, m_IndexWriter.ThisPartition));
- }
-
- // update all Duration properties
- ASDCP::MXF::Partition footer_part(m_Dict);
- DurationElementList_t::iterator dli = m_DurationUpdateList.begin();
-
- for (; dli != m_DurationUpdateList.end(); ++dli )
- {
- **dli = m_FramesWritten;
- }
-
- m_EssenceDescriptor->ContainerDuration = m_FramesWritten;
- footer_part.PreviousPartition = m_RIP.PairArray.back().ByteOffset;
-
- Kumu::fpos_t here = m_File.Tell();
- m_RIP.PairArray.push_back(RIP::Pair(0, here)); // Last RIP Entry
- m_HeaderPart.FooterPartition = here;
-
- assert(m_Dict);
- footer_part.OperationalPattern = m_HeaderPart.OperationalPattern;
- footer_part.EssenceContainers = m_HeaderPart.EssenceContainers;
- footer_part.FooterPartition = here;
- footer_part.ThisPartition = here;
- UL footer_ul(m_Dict->ul(MDD_CompleteFooter));
- Result_t result = footer_part.WriteToFile(m_File, footer_ul);
-
- if ( ASDCP_SUCCESS(result) )
- result = m_RIP.WriteToFile(m_File);
-
- if ( ASDCP_SUCCESS(result) )
- result = m_File.Seek(0);
-
- if ( ASDCP_SUCCESS(result) )
- result = m_HeaderPart.WriteToFile(m_File, m_HeaderSize);
-
- if ( ASDCP_SUCCESS(result) )
- {
- ASDCP::MXF::Array<ASDCP::MXF::RIP::Pair>::const_iterator i = m_RIP.PairArray.begin();
- ui64_t header_byte_count = m_HeaderPart.HeaderByteCount;
- ui64_t previous_partition = 0;
-
- for ( i = m_RIP.PairArray.begin(); ASDCP_SUCCESS(result) && i != m_RIP.PairArray.end(); ++i )
- {
- ASDCP::MXF::Partition plain_part(m_Dict);
- result = m_File.Seek(i->ByteOffset);
-
- if ( ASDCP_SUCCESS(result) )
- result = plain_part.InitFromFile(m_File);
-
- if ( KM_SUCCESS(result)
- && ( plain_part.IndexSID > 0 || plain_part.BodySID > 0 ) )
- {
- plain_part.PreviousPartition = previous_partition;
- plain_part.FooterPartition = footer_part.ThisPartition;
- previous_partition = plain_part.ThisPartition;
- result = m_File.Seek(i->ByteOffset);
-
- if ( ASDCP_SUCCESS(result) )
- {
- UL tmp_ul = plain_part.GetUL();
- result = plain_part.WriteToFile(m_File, tmp_ul);
- }
- }
- }
- }
-
- m_File.Close();
- return result;
-}
//
diff --git a/src/h__Reader.cpp b/src/h__Reader.cpp
index b1c0555..a427fb5 100755
--- a/src/h__Reader.cpp
+++ b/src/h__Reader.cpp
@@ -70,7 +70,7 @@ ASDCP::h__ASDCPReader::~h__ASDCPReader() {}
// AS-DCP method of opening an MXF file for read
Result_t
-ASDCP::h__ASDCPReader::OpenMXFRead(const char* filename)
+ASDCP::h__ASDCPReader::OpenMXFRead(const std::string& filename)
{
Result_t result = ASDCP::MXF::TrackFileReader<OP1aHeader, OPAtomIndexFooter>::OpenMXFRead(filename);