-AS-DCP Lib is Copyright (c) 2003-2009, John Hurst
+AS-DCP Lib is Copyright (c) 2003-2012, John Hurst
All rights reserved.
Redistribution and use in source and binary forms, with or without
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+IMF Essence Component (AS-02) implementation:
+(AS_02.h AS_02_internal.h AS_02_JP2K.cpp AS_02_MXF.cpp AS_02_PCM.cpp
+ as-02-unwrap.cpp as-02-wrap.cpp h__02_Reader.cpp h__02_Writer.cpp)
+Copyright (c) 2011-2012, Robert Scheler, Heiko Sparenberg Fraunhofer IIS, John Hurst
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+3. The name of the author may not be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
The asdcplib library is a set of objects that offer
simplified access to files conforming to the sound and
picture track file formats developed by the SMPTE Working
-Group DC28.20.
+Group DC28.20 (now TC 21DC).
-This work was originally funded by Digital Cinema
-Initiatives, LLC (DCI). Subsequent efforts have been funded
-by Deluxe Laboratories, Doremi Labs, CineCert LLC, Avica
-Technology and others.
+Recently, support has also been added for SMPTE draft ST
+2067-5 "IMF Essence Component", AKA "AS-02". This code was
+donated by Fraunhofer IIS. It carries additional copyright
+information which should be listed whenever you link the
+AS-02 elements of the library. Please look at the top of
+the AS-02 files to see this copyright information.
+
+AS-02 support is carried in separate object modules, so
+unless you #include <AS_02.h> and link libas-02.so you are
+still using plain old asdcp.
+
+This work was originally funded by Digital Cinema Initiatives,
+LLC (DCI). Subsequent efforts have been funded by Deluxe
+Laboratories, Doremi Labs, CineCert LLC, Avica Technology
+and others.
**The asdcplib project was originally housed on SourceForge.
The project has moved to http://www.cinecert.com/asdcplib/
Design Notes
This library is intended (but of course not limited) for
-use by developers of commercial D-Cinema products. It is
-designed to be easily integrated into a wide variety of
-development environments. Commercial users are strongly
-urged to use static linking (at least where you use this
-library) to prevent malicious in-field replacement of
+use by developers of commercial D-Cinema products (and now
+IMF!). It is designed to be easily integrated into a wide
+variety of development environments. Commercial users are
+strongly urged to use static linking (at least where you use
+this library) to prevent malicious in-field replacement of
critical system modules. This recommendation should be
considered wherever Open Source or Free software is being
used in conjunction with critical security parameters, such
implementations of the ASDCP:: objects which provide those
services.
-AS_DCP.h contains the entire API. You do not need to read
-any of the other files, except maybe asdcp-test.cpp which
-contains detailed usage examples of each of the API's
-services. The KM_* files may be of interest for general
-development support, but may be ignored if all you want
-is simple AS-DCP support.
+AS_DCP.h contains the entire AS-DCP API. You do not need to
+read any of the other files, except maybe asdcp-test.cpp which
+contains detailed usage examples of each of the API's services.
+The KM_* files may be of interest for general development
+support, but may be ignored if all you want is simple AS-DCP
+support.
+
+Likewise, draft 2067-5 "IMF Essence Component" (AS-02) support
+is entirely contained in AS-02.h
Build Instructions
this natively, an "nmake" build file and instructions can be found
in the win32 subdirectory.
-OpenSSL is also required, and the most recent version of v0.9.8
-is recommended. See http://www.openssl.org/ for more information
-and download instructions.
+OpenSSL is also required, any recent version should be fine. See
+http://www.openssl.org/ for more information and download instructions.
Optional support for writing Timed Text Track Files is supported by
either Xerces-C or Expat. See http://xerces.apache.org/xerces-c/ or
Documentation
-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.
+The API documentation is mostly in AS_DCP.h. and AS_02.h Read those
+files for a detailed description of the library's capabilities. Read
+asdcp-*.cpp files for library usage examples. The
+command-line utilities all respond to -h.
Change History
+2012-08-07 - bug fix, 1.10.46
+ o Added zero-initializers to time values when parsing a timestamp string
+ (in the case where the (T...) option was not present the time was
+ uninitialized).
+
2012-03-06 - bug fixes, enhancements 1.9.45
o Removed ASDCP::Timestamp, all items that were of that class are now
of class Kumu::Timestamp
# 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.10.45pre1], [asdcplib@cinecert.com])
+AC_INIT([asdcplib], [1.10.45d], [asdcplib@cinecert.com])
AC_CONFIG_AUX_DIR([build-aux])
AC_CONFIG_SRCDIR([src/KM_error.h])
void
Kumu::EntryListLogSink::WriteEntry(const LogEntry& Entry)
{
- AutoMutex L(m_Lock);
+ AutoMutex L(m_lock);
+ WriteEntryToListeners(Entry);
if ( Entry.TestFilter(m_filter) )
m_Target.push_back(Entry);
void
Kumu::StdioLogSink::WriteEntry(const LogEntry& Entry)
{
- AutoMutex L(m_Lock);
std::string buf;
+ AutoMutex L(m_lock);
+ WriteEntryToListeners(Entry);
if ( Entry.TestFilter(m_filter) )
{
void
Kumu::WinDbgLogSink::WriteEntry(const LogEntry& Entry)
{
- AutoMutex L(m_Lock);
std::string buf;
+ AutoMutex L(m_lock);
+ WriteEntryToListeners(Entry);
if ( Entry.TestFilter(m_filter) )
{
void
Kumu::StreamLogSink::WriteEntry(const LogEntry& Entry)
{
- AutoMutex L(m_Lock);
std::string buf;
+ AutoMutex L(m_lock);
+ WriteEntryToListeners(Entry);
if ( Entry.TestFilter(m_filter) )
{
case Kumu::LOG_DEBUG: priority = SYSLOG_DEBUG; break;
}
- AutoMutex L(m_Lock);
+ AutoMutex L(m_lock);
+ WriteEntryToListeners(Entry);
if ( Entry.TestFilter(m_filter) )
{
#include <stdarg.h>
#include <errno.h>
#include <iosfwd>
+#include <set>
#define LOG_MSG_IMPL(t) \
va_list args; \
protected:
i32_t m_filter;
i32_t m_options;
+ Mutex m_lock;
+ std::set<ILogSink*> m_listeners;
+
+ // you must obtain m_lock BEFORE calling this from your own WriteEntry
+ void WriteEntryToListeners(const LogEntry& entry)
+ {
+ std::set<ILogSink*>::iterator i;
+ for ( i = m_listeners.begin(); i != m_listeners.end(); ++i )
+ (*i)->WriteEntry(entry);
+ }
+
+ KM_NO_COPY_CONSTRUCT(ILogSink);
public:
ILogSink() : m_filter(LOG_ALLOW_ALL), m_options(LOG_OPTION_NONE) {}
void UnsetOptionFlag(i32_t o) { m_options &= ~o; }
bool TestOptionFlag(i32_t o) const { return ((m_options & o) == o); }
+ void AddListener(ILogSink& s) {
+ if ( &s != this )
+ {
+ AutoMutex l(m_lock);
+ m_listeners.insert(&s);
+ }
+ }
+
+ void DelListener(ILogSink& s) {
+ AutoMutex l(m_lock);
+ m_listeners.erase(&s);
+ }
+
// library messages
void Error(const char* fmt, ...) { LOG_MSG_IMPL(LOG_ERROR); }
void Warn(const char* fmt, ...) { LOG_MSG_IMPL(LOG_WARN); }
ILogSink& DefaultLogSink();
- // Sets a log sink as the default until the object is destroyed.
- // The original default sink is saved and then restored on delete.
- class LogSinkContext
- {
- KM_NO_COPY_CONSTRUCT(LogSinkContext);
- LogSinkContext();
- ILogSink* m_orig;
+ // attach a log sink as a listener until deleted
+ class LogSinkListenContext
+ {
+ ILogSink* m_log_source;
+ ILogSink* m_sink;
+ KM_NO_COPY_CONSTRUCT(LogSinkListenContext);
+ LogSinkListenContext();
+
+ public:
+ LogSinkListenContext(ILogSink& source, ILogSink& sink)
+ {
+ m_log_source = &source;
+ m_sink = &sink;
+ m_log_source->AddListener(*m_sink);
+ }
+
+ ~LogSinkListenContext()
+ {
+ m_log_source->DelListener(*m_sink);
+ }
+ };
- public:
- LogSinkContext(ILogSink& sink) {
- m_orig = &DefaultLogSink();
- SetDefaultLogSink(&sink);
- }
-
- ~LogSinkContext() {
- SetDefaultLogSink(m_orig);
- }
- };
//------------------------------------------------------------------------------------------
//
- // write messages to two subordinate log sinks
- class TeeLogSink : public ILogSink
- {
- KM_NO_COPY_CONSTRUCT(TeeLogSink);
- TeeLogSink();
-
- ILogSink& m_a;
- ILogSink& m_b;
-
- public:
- TeeLogSink(ILogSink& a, ILogSink& b) : m_a(a), m_b(b) {}
- virtual ~TeeLogSink() {}
-
- void WriteEntry(const LogEntry& Entry) {
- m_a.WriteEntry(Entry);
- m_b.WriteEntry(Entry);
- }
- };
-
// collect log messages into the given list, does not test filter
class EntryListLogSink : public ILogSink
{
- Mutex m_Lock;
LogEntryList& m_Target;
KM_NO_COPY_CONSTRUCT(EntryListLogSink);
EntryListLogSink();
// write messages to a POSIX stdio stream
class StdioLogSink : public ILogSink
{
- Mutex m_Lock;
FILE* m_stream;
KM_NO_COPY_CONSTRUCT(StdioLogSink);
// write messages to the Win32 debug stream
class WinDbgLogSink : public ILogSink
{
- Mutex m_Lock;
KM_NO_COPY_CONSTRUCT(WinDbgLogSink);
public:
// write messages to a POSIX file descriptor
class StreamLogSink : public ILogSink
{
- Mutex m_Lock;
int m_fd;
KM_NO_COPY_CONSTRUCT(StreamLogSink);
StreamLogSink();
// write messages to the syslog facility
class SyslogLogSink : public ILogSink
{
- Mutex m_Lock;
KM_NO_COPY_CONSTRUCT(SyslogLogSink);
SyslogLogSink();
return str_buf;
}
-//
+// ^(\d{4})-(\d{2})-(\d{2})(?:T(\d{2}):(\d{2})(?::(\d{2})(?:\.(\d+))?)?(?:([+-]\d{2}):(\d{2}))?)?$
bool
Kumu::Timestamp::DecodeString(const char* datestr)
{
ui32_t char_count = 10;
TAI::caltime YMDhms;
+ YMDhms.hour = 0;
+ YMDhms.minute = 0;
+ YMDhms.second = 0;
YMDhms.offset = 0;
YMDhms.date.year = atoi(datestr);
YMDhms.date.month = atoi(datestr + 5);
return m_Timestamp.x - ui64_C(4611686018427387914);
}
+//
+void
+Kumu::Timestamp::SetCTime(const ui64_t& ctime)
+{
+ m_Timestamp.x = ctime + ui64_C(4611686018427387914);
+}
+
+
+
//------------------------------------------------------------------------------------------
virtual ~ArchivableString() {}
bool HasValue() const { return ! this->empty(); }
- ui32_t ArchiveLength() const { return static_cast<ui32_t>((sizeof(ui32_t) + this->size())|0xffffffff); }
+ ui32_t ArchiveLength() const { sizeof(ui32_t) + static_cast<ui32_t>(this->size()); }
bool Archive(MemIOWriter* Writer) const {
if ( Writer == 0 ) return false;
// Return the number of seconds since the Unix epoch UTC (1970-01-01T00:00:00+00:00)
ui64_t GetCTime() const;
+ // Set internal time to the number of seconds since the Unix epoch UTC
+ void SetCTime(const ui64_t& ctime);
+
// Read and write the timestamp (always UTC) value as a byte string having
// the following format:
// | 16 bits int, big-endian | 8 bits | 8 bits | 8 bits | 8 bits | 8 bits |
if ( ! XML_Parse(Parser, document, doc_len, 1) )
{
- XML_ParserFree(Parser);
DefaultLogSink().Error("XML Parse error on line %d: %s\n",
XML_GetCurrentLineNumber(Parser),
XML_ErrorString(XML_GetErrorCode(Parser)));
+ XML_ParserFree(Parser);
return false;
}
# list of all the header files that should be installed
include_HEADERS = KM_error.h KM_fileio.h KM_log.h KM_memio.h KM_mutex.h \
- KM_platform.h KM_prng.h KM_util.h KM_tai.h KM_xml.h AS_DCP.h AS_02.h
+ KM_platform.h KM_prng.h KM_util.h KM_tai.h KM_xml.h AS_DCP.h
+
if DEV_HEADERS
include_HEADERS += S12MTimecode.h MDD.h Metadata.h KLV.h MXFTypes.h MXF.h Wav.h \
PCMParserList.h
# list of the libraries to build and install
-lib_LTLIBRARIES = libkumu.la libasdcp.la libas02.la
+lib_LTLIBRARIES = libkumu.la libasdcp.la
# sources for kumu library
libkumu_la_SOURCES = KM_error.h KM_fileio.cpp KM_fileio.h KM_log.cpp KM_log.h \
libasdcp_la_CPPFLAGS = -DASDCP_PLATFORM=\"@host@\"
-# sources for as-02 library
-libas02_la_SOURCES = \
- AS_02.h AS_02_MXF.cpp AS_02_JP2K.cpp AS_02_PCM.cpp h__02_Reader.cpp h__02_Writer.cpp AS_02_internal.h
-libas02_la_LDFLAGS = -release @VERSION@
-libas02_la_LIBADD = libasdcp.la libkumu.la
-libas02_la_CPPFLAGS = -DASDCP_PLATFORM=\"@host@\"
-
-
# Python extension
if PYTHON_USE
lib_LTLIBRARIES += libpyasdcp.la
# list of programs to be built and installed
bin_PROGRAMS = \
asdcp-wrap asdcp-unwrap asdcp-util asdcp-info asdcp-test \
- as-02-wrap as-02-unwrap \
j2c-test blackwave klvwalk wavesplit \
- kmfilegen kmrandgen kmuuidgen
+ kmfilegen kmrandgen kmuuidgen
# sources and linkage for CLI utilities
asdcp_test_SOURCES = asdcp-test.cpp
asdcp_test_LDADD = libasdcp.la
-as_02_wrap_SOURCES = as-02-wrap.cpp
-as_02_wrap_LDADD = libas02.la
-
-as_02_unwrap_SOURCES = as-02-unwrap.cpp
-as_02_unwrap_LDADD = libas02.la
-
asdcp_wrap_SOURCES = asdcp-wrap.cpp
asdcp_wrap_LDADD = libasdcp.la
\n\
%s -d <input-file>\n\
\n\
- %s -g | -u\n\
-\n\
- %s -u\n\n",
+ %s -g | -u\n",
PROGRAM_NAME, PROGRAM_NAME, PROGRAM_NAME, PROGRAM_NAME);
fprintf(stream, "\