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)
}
// 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) /
};
namespace JP2K
- {
+ {
//
class MXFWriter
{
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
// 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;
ASDCP_NO_COPY_CONSTRUCT(h__Reader);
public:
- PictureDescriptor m_PDesc; // codestream parameter list
-
h__Reader(const Dictionary& d) :
AS_02::h__AS02Reader(d) {}
//------------------------------------------------------------------------------------------
//
-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();
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);
}
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;
{
ui64_t m_ClipEssenceBegin;
ui64_t m_SamplesPerFrame;
+ ui32_t m_BytesPerFrame;
ui32_t m_ContainerDuration;
ASDCP_NO_COPY_CONSTRUCT(h__Reader);
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);
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);
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)));
+
}
}
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;
}
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);
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;
//------------------------------------------------------------------------------------------
//
-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();
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);
}
{
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;
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;
if ( KM_SUCCESS(result) )
{
- m_FramesWritten++;
+ m_FramesWritten += m_SamplesPerFrame;
}
return result;
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();
}
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
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
// 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
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);
//---------------------------------------------------------------------------------
// 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.
// 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
// 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;
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
};
// 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.
// 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
// 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;
// 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.
// 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
// 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
// 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;
// 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
// 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;
// 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.
// 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
// 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;
// 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.
// 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
// 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
// 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;
// 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
// 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
// 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;
//
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;
}
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);
};
//
//
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);
// 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);
}
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);
};
//
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);
// 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 )
//
//
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);
// 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);
}
//
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() )
// 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 )
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);
};
~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();
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*);
};
//
//
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);
// 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);
}
// 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);
}
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*);
// 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;
// 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 )
// 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 )
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&);
//
//
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);
// 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);
}
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();
// 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;
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));
// 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 )
//
//
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);
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;
}
}
//
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;
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) )
{
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;
}
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;
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;
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;
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*);
};
//
//
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);
// 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);
}
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();
// 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;
// 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 )
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);
//
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);
// 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);
}
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);
//
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;
// 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 )
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);
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,
~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);
// 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);
}
//
- Result_t InitFromDirectory(const char* path)
+ Result_t InitFromDirectory(const std::string& path)
{
char next_file[Kumu::MaxFilePath];
Kumu::DirScanner Scanner;
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() {}
//
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) )
// 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;
/*
-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
~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);
// 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);
}
//
- Result_t InitFromDirectory(const char* path)
+ Result_t InitFromDirectory(const std::string& path)
{
char next_file[Kumu::MaxFilePath];
Kumu::DirScanner Scanner;
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() {}
//
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);
// 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;
//
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
//
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
//
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;
}
//
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;
}
//
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;
}
//
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) )
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;
}
//
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);
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);
if ( KM_SUCCESS(result) )
{
Buffer.Length(MemWriter.Length());
- result = Writer.OpenWrite(Filename.c_str());
+ result = Writer.OpenWrite(Filename);
}
if ( KM_SUCCESS(result) )
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);
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);
//
//
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 != '\\' )
//
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 )
{
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;
}
}
DirScanner(void);
~DirScanner() { Close(); }
- Result_t Open(const char*);
+ Result_t Open(const std::string&);
Result_t Close();
Result_t GetNext(char*);
};
// 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
//
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
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*),
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&);
//
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);
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();
}
// 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;
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;
// 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) )
{
return RESULT_FAIL;
}
+//
+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)
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;
}
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;
}
//
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);
}
//
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;
{
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;
}
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);
{
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;
}
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;
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++;
}
else if ( ! isspace(*i) )
{
- fprintf(stderr, "Unexpected character '%c'.\n", *i);
+ DefaultLogSink().Error("Unexpected character '%c'.\n", *i);
return false;
}
}
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++;
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)));
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);
}
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);
//
class IndexTableSegment : public InterchangeObject
{
+ IndexTableSegment();
ASDCP_NO_COPY_CONSTRUCT(IndexTableSegment);
public:
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; }
ui32_t m_BytesPerEditUnit;
Rational m_EditRate;
ui32_t m_BodySID;
+ IndexTableSegment::DeltaEntry m_DefaultDeltaEntry;
ASDCP_NO_COPY_CONSTRUCT(OPAtomIndexFooter);
OPAtomIndexFooter();
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);
};
};
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
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
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
/*
-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
// 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) )
/*
-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
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; }
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&);
//
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) )
// 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;
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;
};
//
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);
//
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();
}
// 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;
// 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;
/*
-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.
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);
}
}
{
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;
{
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);
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;
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;
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) )
}
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) )
}
// 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
}
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() )
{
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) )
}
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() )
{
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 )
}
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()
}
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) )
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) )
}
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) )
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) )
}
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) )
}
EssenceType_t EssenceType;
- result = ASDCP::RawEssenceType(Options.filenames.front().c_str(), EssenceType);
+ result = ASDCP::RawEssenceType(Options.filenames.front(), EssenceType);
if ( ASDCP_SUCCESS(result) )
{
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 )
{
}
}
+ DefaultLogSink().Error("AS_02::MXF::AS02IndexReader::Lookup FAILED: frame_num=%d\n", frame_num);
return RESULT_FAIL;
}
//------------------------------------------------------------------------------------------
//
-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;
//
void
-AS_02::MXF::AS02IndexWriter::Dump(FILE* stream)
+AS_02::MXF::AS02IndexWriterVBR::Dump(FILE* stream)
{
if ( stream == 0 )
stream = stderr;
//
ui32_t
-AS_02::MXF::AS02IndexWriter::GetDuration() const
+AS_02::MXF::AS02IndexWriterVBR::GetDuration() const
{
ui32_t duration = 0;
std::list<InterchangeObject*>::const_iterator i;
//
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
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);
}
//
//
-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
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 )
{
//
Result_t
-AS_02::h__AS02Writer::WriteClipBlock(const ASDCP::FrameBuffer& FrameBuf)
+AS_02::h__AS02WriterClip::WriteClipBlock(const ASDCP::FrameBuffer& FrameBuf)
{
if ( m_ClipStart == 0 )
{
//
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 )
{
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;
-}
//
// 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);