Documentation
-Currently, the API documentation is mostly in AS_DCP.h. Read
-that file for a detailed description of the library's capabilities.
-Read asdcp-test.cpp for library usage examples. The command-line
+The API documentation is mostly in AS_DCP.h. Read that file for
+a detailed description of the library's capabilities. Read
+asdcp-test.cpp for library usage examples. The command-line
utilities all respond to -h.
Change History
-NEW STUFF:
+2010.05.13 - bug fixes, enhancements, v1.6.34
+ o ST 429-5 files have corrected ULs for DCTimedTextDescriptor and
+ GenericStream DataElement. Files made with previous versions of
+ the library are incompatible with this and future versions.
+ o Fixed File Package TrackNumber values. Thanks to Sankar.
+ o Added edit rate constants to AS_DCP.h (25, 30, 50, 60).
o Changed AudioDescriptor "SampelRate" element name to "EditRate"
- to make it consistent with the other types.
- o Now builds with XercesC 3.x
- o KM_memio.h has better const behavior
+ to make it consistent with the other types.
+ o Now builds with XercesC 3.x.
+ o KM_memio.h has better const behavior.
+ o Fixed a bug in KM_memio.h string archiving.
2010.01.05 - bug fixes, enhancements, v1.5.32
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
-# Copyright (c) 2007-2009 John Hurst. All rights reserved.
+# Copyright (c) 2007-2010 John Hurst. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# For example, if asdcplib version 1.0.0 were modified to accomodate changes
# in file format, and if no changes were made to AS_DCP.h, the new version would be
# 1.0.1. If changes were also required in AS_DCP.h, the new version would be 1.1.1.
-AC_INIT([asdcplib], [1.5.33], [asdcplib@cinecert.com])
+AC_INIT([asdcplib], [1.6.34], [asdcplib@cinecert.com])
AC_CONFIG_AUX_DIR([build-aux])
AC_CONFIG_SRCDIR([src/KM_error.h])
/*
-Copyright (c) 2003-2009, John Hurst
+Copyright (c) 2003-2010, John Hurst
All rights reserved.
Redistribution and use in source and binary forms, with or without
const Rational SampleRate_48k(48000,1);
const Rational SampleRate_96k(96000,1);
- // Additional frame rates, see SMPTE 428-11
- // These rates are new and not supported by all systems. Do not assume that a package
- // made using on of these rates will work just anywhere!
+ // Additional frame rates, see ST 428-11
+ // These rates are new and not supported by all systems. Do not assume that
+ // a package made using on of these rates will work just anywhere!
const Rational EditRate_25(25,1);
const Rational EditRate_30(30,1);
const Rational EditRate_50(50,1);
/*
-Copyright (c) 2004-2009, John Hurst
+Copyright (c) 2004-2010, John Hurst
All rights reserved.
Redistribution and use in source and binary forms, with or without
m_PDesc = PDesc;
Result_t result = JP2K_PDesc_to_MD(m_PDesc);
- if ( ASDCP_SUCCESS(result) )
- result = WriteMXFHeader(label, UL(m_Dict->ul(MDD_JPEG_2000Wrapping)),
- PICT_DEF_LABEL, UL(m_Dict->ul(MDD_PictureDataDef)),
- LocalEditRate, 24 /* TCFrameRate */);
-
if ( ASDCP_SUCCESS(result) )
{
memcpy(m_EssenceUL, m_Dict->ul(MDD_JPEG2000Essence), SMPTE_UL_LENGTH);
result = m_State.Goto_READY();
}
+ if ( ASDCP_SUCCESS(result) )
+ result = WriteMXFHeader(label, UL(m_Dict->ul(MDD_JPEG_2000Wrapping)),
+ PICT_DEF_LABEL, UL(m_EssenceUL), UL(m_Dict->ul(MDD_PictureDataDef)),
+ LocalEditRate, 24 /* TCFrameRate */);
+
return result;
}
/*
-Copyright (c) 2004-2009, John Hurst
+Copyright (c) 2004-2010, John Hurst
All rights reserved.
Redistribution and use in source and binary forms, with or without
m_VDesc = VDesc;
Result_t result = MPEG2_VDesc_to_MD(m_VDesc, (MPEG2VideoDescriptor*)m_EssenceDescriptor);
- if ( ASDCP_SUCCESS(result) )
- result = WriteMXFHeader(MPEG_PACKAGE_LABEL, UL(m_Dict->ul(MDD_MPEG2_VESWrapping)),
- PICT_DEF_LABEL, UL(m_Dict->ul(MDD_PictureDataDef)),
- m_VDesc.EditRate, 24 /* TCFrameRate */);
-
if ( ASDCP_SUCCESS(result) )
{
memcpy(m_EssenceUL, m_Dict->ul(MDD_MPEG2Essence), SMPTE_UL_LENGTH);
result = m_State.Goto_READY();
}
+ if ( ASDCP_SUCCESS(result) )
+ result = WriteMXFHeader(MPEG_PACKAGE_LABEL, UL(m_Dict->ul(MDD_MPEG2_VESWrapping)),
+ PICT_DEF_LABEL, UL(m_EssenceUL), UL(m_Dict->ul(MDD_PictureDataDef)),
+ m_VDesc.EditRate, 24 /* TCFrameRate */);
+
return result;
}
/*
-Copyright (c) 2004-2009, John Hurst
+Copyright (c) 2004-2010, John Hurst
All rights reserved.
Redistribution and use in source and binary forms, with or without
Result_t result = PCM_ADesc_to_MD(m_ADesc, (WaveAudioDescriptor*)m_EssenceDescriptor);
- if ( ASDCP_SUCCESS(result) )
- result = WriteMXFHeader(PCM_PACKAGE_LABEL, UL(m_Dict->ul(MDD_WAVWrapping)),
- SOUND_DEF_LABEL, UL(m_Dict->ul(MDD_SoundDataDef)),
- m_ADesc.EditRate, TCFrameRate, calc_CBR_frame_size(m_Info, m_ADesc));
-
if ( ASDCP_SUCCESS(result) )
{
memcpy(m_EssenceUL, m_Dict->ul(MDD_WAVEssence), SMPTE_UL_LENGTH);
result = m_State.Goto_READY();
}
+ if ( ASDCP_SUCCESS(result) )
+ result = WriteMXFHeader(PCM_PACKAGE_LABEL, UL(m_Dict->ul(MDD_WAVWrapping)),
+ SOUND_DEF_LABEL, UL(m_EssenceUL), UL(m_Dict->ul(MDD_SoundDataDef)),
+ m_ADesc.EditRate, TCFrameRate, calc_CBR_frame_size(m_Info, m_ADesc));
+
return result;
}
void InitHeader();
void AddSourceClip(const MXF::Rational& EditRate, ui32_t TCFrameRate,
- const std::string& TrackName, const UL& DataDefinition,
- const std::string& PackageLabel);
+ const std::string& TrackName, const UL& EssenceUL,
+ const UL& DataDefinition, const std::string& PackageLabel);
void AddDMSegment(const MXF::Rational& EditRate, ui32_t TCFrameRate,
- const std::string& TrackName, const UL& DataDefinition,
+ const std::string& TrackName, const UL& DataDefinition,
const std::string& PackageLabel);
void AddEssenceDescriptor(const UL& WrappingUL);
Result_t CreateBodyPart(const MXF::Rational& EditRate, ui32_t BytesPerEditUnit = 0);
// all the above for a single source clip
Result_t WriteMXFHeader(const std::string& PackageLabel, const UL& WrappingUL,
- const std::string& TrackName, const UL& DataDefinition,
- const MXF::Rational& EditRate,
+ const std::string& TrackName, const UL& EssenceUL,
+ const UL& DataDefinition, const MXF::Rational& EditRate,
ui32_t TCFrameRate, ui32_t BytesPerEditUnit = 0);
Result_t WriteEKLVPacket(const ASDCP::FrameBuffer& FrameBuf,
/*
-Copyright (c) 2006-2009, John Hurst
+Copyright (c) 2006-2010, John Hurst
All rights reserved.
Redistribution and use in source and binary forms, with or without
m_size += sizeof(ui64_t);
return true;
}
+
+ inline bool WriteString(const std::string& str)
+ {
+ if ( ! WriteUi32BE(str.length()) ) return false;
+ if ( ! WriteRaw((const byte_t*)str.c_str(), str.length()) ) return false;
+ return true;
+ }
};
//
m_size += sizeof(ui64_t);
return true;
}
+
+ inline bool ReadString(std::string& str)
+ {
+ ui32_t str_length;
+ if ( ! ReadUi32BE(&str_length) ) return false;
+ if ( ( m_size + str_length ) > m_capacity ) return false;
+ str.assign((const char*)CurrentData(), str_length);
+ if ( ! SkipOffset(str_length) ) return false;
+ return true;
+ }
};
//
inline bool
- UnarchiveString(MemIOReader& Reader, std::string& str)
- {
- ui32_t str_length;
- if ( ! Reader.ReadUi32BE(&str_length) ) return false;
- str.assign((const char*)Reader.CurrentData(), str_length);
- if ( ! Reader.SkipOffset(str_length) ) return false;
- return true;
- }
+ UnarchiveString(MemIOReader& Reader, std::string& str) {
+ return Reader.ReadString(str);
+ }
//
inline bool
- ArchiveString(MemIOWriter& Writer, const std::string& str)
- {
- if ( ! Writer.WriteUi32BE(str.length()) ) return false;
- if ( ! Writer.WriteRaw((const byte_t*)str.c_str(), str.length()) ) return false;
- return true;
- }
+ ArchiveString(MemIOWriter& Writer, const std::string& str)
+ {
+ return Writer.WriteString(str);
+ }
+
} // namespace Kumu
}
};
+ // archivable version of std::string
+
+ //
+ class ArchivableString : public std::string, public Kumu::IArchive
+ {
+
+ public:
+ ArchivableString() {}
+ ArchivableString(const char* sz) : std::string(sz) {}
+ ArchivableString(const std::string& s) : std::string(s) {}
+ virtual ~ArchivableString() {}
+
+ bool HasValue() const { return ! this->empty(); }
+ ui32_t ArchiveLength() const { return sizeof(ui32_t) + this->size(); }
+
+ bool Archive(MemIOWriter* Writer) const {
+ if ( Writer == 0 ) return false;
+ return Writer->WriteString(*this);
+ }
+
+ bool Unarchive(MemIOReader* Reader) {
+ if ( Reader == 0 ) return false;
+ return Reader->ReadString(*this);
+ }
+ };
+
+ //
+ typedef Kumu::ArchivableList<ArchivableString> StringList;
+
//
// the base of all identifier classes, Identifier is not usually used directly
// see UUID and SymmetricKey below for more detail.
{ { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x02, 0x01, 0x09, // 256
0x0d, 0x01, 0x03, 0x01, 0x17, 0x01, 0x0b, 0x01 },
{0}, false, "TimedTextEssence" },
- { { 0x06, 0x0e, 0x2b, 0x34, 0x02, 0x7f, 0x01, 0x01, // 257
+ { { 0x06, 0x0e, 0x2b, 0x34, 0x02, 0x53, 0x01, 0x01, // 257
0x0d, 0x01, 0x01, 0x01, 0x01, 0x01, 0x64, 0x00 },
{0}, false, "TimedTextDescriptor" },
{ { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x0c, // 258
0x04, 0x02, 0x01, 0x01, 0x05, 0x00, 0x00, 0x00 },
{0x3d, 0x32}, true, "WaveAudioDescriptor_ChannelAssignment" },
{ { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x0c, // 271
- 0x0d, 0x01, 0x05, 0x05, 0x01, 0x00, 0x00, 0x00 },
+ 0x0d, 0x01, 0x05, 0x09, 0x01, 0x00, 0x00, 0x00 },
{0x00, 0x00}, false, "GenericStream_DataElement" },
{ { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02, // 272
0x06, 0x01, 0x01, 0x04, 0x06, 0x10, 0x00, 0x00 },
/*
-Copyright (c) 2004-2009, John Hurst
+Copyright (c) 2004-2010, John Hurst
All rights reserved.
Redistribution and use in source and binary forms, with or without
//
void
ASDCP::h__Writer::AddSourceClip(const MXF::Rational& EditRate, ui32_t TCFrameRate,
- const std::string& TrackName, const UL& DataDefinition,
- const std::string& PackageLabel)
+ const std::string& TrackName, const UL& EssenceUL,
+ const UL& DataDefinition, const std::string& PackageLabel)
{
//
ContentStorage* Storage = new ContentStorage(m_Dict);
m_HeaderPart.AddChildObject(m_MaterialPackage);
Storage->Packages.push_back(m_MaterialPackage->InstanceUID);
- TrackSet<TimecodeComponent> MPTCTrack = CreateTimecodeTrack<MaterialPackage>(m_HeaderPart, *m_MaterialPackage,
- EditRate, TCFrameRate, 0, m_Dict);
+ TrackSet<TimecodeComponent> MPTCTrack =
+ CreateTimecodeTrack<MaterialPackage>(m_HeaderPart, *m_MaterialPackage,
+ EditRate, TCFrameRate, 0, m_Dict);
m_DurationUpdateList.push_back(&(MPTCTrack.Sequence->Duration));
m_DurationUpdateList.push_back(&(MPTCTrack.Clip->Duration));
- TrackSet<SourceClip> MPTrack = CreateTrackAndSequence<MaterialPackage, SourceClip>(m_HeaderPart, *m_MaterialPackage,
- TrackName, EditRate, DataDefinition,
- 2, m_Dict);
+ TrackSet<SourceClip> MPTrack =
+ CreateTrackAndSequence<MaterialPackage, SourceClip>(m_HeaderPart, *m_MaterialPackage,
+ TrackName, EditRate, DataDefinition,
+ 2, m_Dict);
m_DurationUpdateList.push_back(&(MPTrack.Sequence->Duration));
MPTrack.Clip = new SourceClip(m_Dict);
m_HeaderPart.AddChildObject(m_FilePackage);
Storage->Packages.push_back(m_FilePackage->InstanceUID);
- TrackSet<TimecodeComponent> FPTCTrack = CreateTimecodeTrack<SourcePackage>(m_HeaderPart, *m_FilePackage,
- EditRate, TCFrameRate,
- ui64_C(3600) * TCFrameRate, m_Dict);
+ TrackSet<TimecodeComponent> FPTCTrack =
+ CreateTimecodeTrack<SourcePackage>(m_HeaderPart, *m_FilePackage,
+ EditRate, TCFrameRate,
+ ui64_C(3600) * TCFrameRate, m_Dict);
m_DurationUpdateList.push_back(&(FPTCTrack.Sequence->Duration));
m_DurationUpdateList.push_back(&(FPTCTrack.Clip->Duration));
-
- TrackSet<SourceClip> FPTrack = CreateTrackAndSequence<SourcePackage, SourceClip>(m_HeaderPart, *m_FilePackage,
- TrackName, EditRate, DataDefinition,
- 2, m_Dict);
+ TrackSet<SourceClip> FPTrack =
+ CreateTrackAndSequence<SourcePackage, SourceClip>(m_HeaderPart, *m_FilePackage,
+ TrackName, EditRate, DataDefinition,
+ 2, m_Dict);
m_DurationUpdateList.push_back(&(FPTrack.Sequence->Duration));
+ // Consult ST 379:2004 Sec. 6.3, "Element to track relationship" to see where "12" comes from.
+ FPTrack.Track->TrackNumber = KM_i32_BE(Kumu::cp2i<ui32_t>((EssenceUL.Value() + 12)));
+
FPTrack.Clip = new SourceClip(m_Dict);
m_HeaderPart.AddChildObject(FPTrack.Clip);
FPTrack.Sequence->StructuralComponents.push_back(FPTrack.Clip->InstanceUID);
//
void
ASDCP::h__Writer::AddDMSegment(const MXF::Rational& EditRate, ui32_t TCFrameRate,
- const std::string& TrackName, const UL& DataDefinition,
+ const std::string& TrackName, const UL& DataDefinition,
const std::string& PackageLabel)
{
//
m_HeaderPart.AddChildObject(m_MaterialPackage);
Storage->Packages.push_back(m_MaterialPackage->InstanceUID);
- TrackSet<TimecodeComponent> MPTCTrack = CreateTimecodeTrack<MaterialPackage>(m_HeaderPart, *m_MaterialPackage,
- EditRate, TCFrameRate, 0, m_Dict);
+ TrackSet<TimecodeComponent> MPTCTrack =
+ CreateTimecodeTrack<MaterialPackage>(m_HeaderPart, *m_MaterialPackage,
+ EditRate, TCFrameRate, 0, m_Dict);
m_DurationUpdateList.push_back(&(MPTCTrack.Sequence->Duration));
m_DurationUpdateList.push_back(&(MPTCTrack.Clip->Duration));
- TrackSet<DMSegment> MPTrack = CreateTrackAndSequence<MaterialPackage, DMSegment>(m_HeaderPart, *m_MaterialPackage,
- TrackName, EditRate, DataDefinition,
- 2, m_Dict);
+ TrackSet<DMSegment> MPTrack =
+ CreateTrackAndSequence<MaterialPackage, DMSegment>(m_HeaderPart, *m_MaterialPackage,
+ TrackName, EditRate, DataDefinition,
+ 2, m_Dict);
m_DurationUpdateList.push_back(&(MPTrack.Sequence->Duration));
MPTrack.Clip = new DMSegment(m_Dict);
m_HeaderPart.AddChildObject(m_FilePackage);
Storage->Packages.push_back(m_FilePackage->InstanceUID);
- TrackSet<TimecodeComponent> FPTCTrack = CreateTimecodeTrack<SourcePackage>(m_HeaderPart, *m_FilePackage,
- EditRate, TCFrameRate,
- ui64_C(3600) * TCFrameRate, m_Dict);
+ TrackSet<TimecodeComponent> FPTCTrack =
+ CreateTimecodeTrack<SourcePackage>(m_HeaderPart, *m_FilePackage,
+ EditRate, TCFrameRate,
+ ui64_C(3600) * TCFrameRate, m_Dict);
m_DurationUpdateList.push_back(&(FPTCTrack.Sequence->Duration));
m_DurationUpdateList.push_back(&(FPTCTrack.Clip->Duration));
- TrackSet<DMSegment> FPTrack = CreateTrackAndSequence<SourcePackage, DMSegment>(m_HeaderPart, *m_FilePackage,
- TrackName, EditRate, DataDefinition,
- 2, m_Dict);
+ TrackSet<DMSegment> FPTrack =
+ CreateTrackAndSequence<SourcePackage, DMSegment>(m_HeaderPart, *m_FilePackage,
+ TrackName, EditRate, DataDefinition,
+ 2, m_Dict);
m_DurationUpdateList.push_back(&(FPTrack.Sequence->Duration));
FPTrack.Clip = new DMSegment(m_Dict);
//
Result_t
ASDCP::h__Writer::WriteMXFHeader(const std::string& PackageLabel, const UL& WrappingUL,
- const std::string& TrackName, const UL& DataDefinition,
+ const std::string& TrackName, const UL& EssenceUL, const UL& DataDefinition,
const MXF::Rational& EditRate, ui32_t TCFrameRate, ui32_t BytesPerEditUnit)
{
InitHeader();
- AddSourceClip(EditRate, TCFrameRate, TrackName, DataDefinition, PackageLabel);
+ AddSourceClip(EditRate, TCFrameRate, TrackName, EssenceUL, DataDefinition, PackageLabel);
AddEssenceDescriptor(WrappingUL);
Result_t result = m_HeaderPart.WriteToFile(m_File, m_HeaderSize);
is needed. That said, the latest revision of OpenSSL as of this writing (0.9.8j) works great.\r
Extract and build in the directory of your choice.\r
\r
-For optional XML parsing support, you'll need to use Xerces-C++ 2.7 or 2.8 (3.0 isn't yet\r
-supported) or Expat 2.0.1 (supported in previous versions of asdcplib). If you'll be using this\r
-software in conjuction with CineCert's other software, the use of Xerces-C++ is required. As\r
-with OpenSSL above, if you need/desire XML parsing, extract the source package and build in a\r
-directory of your choice.\r
+For optional XML parsing support, you'll need to use Xerces-C++ 2.7 or 3.x, or Expat 2.0.1\r
+(supported in previous versions of asdcplib). If you'll be using this software in conjuction with\r
+CineCert's other software, the use of Xerces-C++ is required. As with OpenSSL above, if you\r
+need/desire XML parsing, extract the source package and build in a directory of your choice.\r
\r
Header files and libraries from the OpenSSL and XML packages must be available to the compiler\r
and linker. You may need to modify the makefile to make include files (/I...) and library files\r
C:\Program Files\asdcplib\win32>nmake WITH_OPENSSL="c:\Program Files\openssl-0.9.8j"\r
/f Makefile.mak\r
\r
+Want a 64-bit build? Change the following line in Makefile.mak:\r
+ LINKFLAGS1 = /NOLOGO /SUBSYSTEM:console /MACHINE:I386 /LIBPATH:. /DEBUG\r
+to\r
+ LINKFLAGS1 = /NOLOGO /SUBSYSTEM:console /MACHINE:X64 /LIBPATH:. /DEBUG\r
+\r
\r
IV. CONCLUSION\r
==============\r