summaryrefslogtreecommitdiff
path: root/src/MXFTypes.cpp
diff options
context:
space:
mode:
authorjhurst <jhurst@cinecert.com>2006-03-11 01:43:02 +0000
committerjhurst <>2006-03-11 01:43:02 +0000
commit9bfe9676115531eb76649e1ebd5e14b904b53ae2 (patch)
treedf29b4a9f7d1bbb00821560ac3bca69ec7982683 /src/MXFTypes.cpp
parente73ef2046cf4f6beb730be071022aaedb3b44bba (diff)
metadata reformed...
Diffstat (limited to 'src/MXFTypes.cpp')
-rwxr-xr-xsrc/MXFTypes.cpp381
1 files changed, 366 insertions, 15 deletions
diff --git a/src/MXFTypes.cpp b/src/MXFTypes.cpp
index 2a8949e..6001cf3 100755
--- a/src/MXFTypes.cpp
+++ b/src/MXFTypes.cpp
@@ -30,13 +30,130 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "MXFTypes.h"
+#include "FortunaRNG.h"
//------------------------------------------------------------------------------------------
//
+const ASDCP::UID&
+ASDCP::UID::operator=(const UMID& rhs)
+{
+ // TODO
+ return *this;
+}
+
+//
+void
+ASDCP::UMID::MakeUMID(int Type)
+{
+ UUID AssetID;
+ AssetID.GenRandomValue();
+ MakeUMID(Type, AssetID);
+}
+
+//
+void
+ASDCP::UMID::MakeUMID(int Type, const UUID& AssetID)
+{
+ // Set the non-varying base of the UMID
+ static const byte_t UMIDBase[10] = { 0x06, 0x0a, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 };
+ memcpy(m_Value, UMIDBase, 10);
+
+ // Correct to v5 dictionary for new (330M-2003) types
+ if( Type > 4 )
+ m_Value[7] = 5;
+
+ // Set the type
+ m_Value[10] = Type;
+
+ // We are using a GUID for material number, and no defined instance method
+ m_Value[11] = 0x20;
+
+ // Length of UMID "Value" is 19 bytes
+ m_Value[12] = 0x13;
+
+ // Set instance number to zero as this is the first instance of this material
+ m_Value[13] = m_Value[14] = m_Value[15] = 0;
+
+ memcpy(&m_Value[16], AssetID.Value(), AssetID.Size());
+}
+
+
+// Write the timestamp value to the given buffer in the form 2004-05-01 13:20:00.000
+// returns 0 if the buffer is smaller than DateTimeLen
+const char*
+ASDCP::UMID::ToString(char* str_buf) const
+{
+ assert(str_buf);
+
+ snprintf(str_buf, IdentBufferLen, "[%02x%02x%02x%02x.%02x%02x.%02x%02x.%02x%02x%02x%02x],%02x,%02x,%02x,%02x,",
+ m_Value[0], m_Value[1], m_Value[2], m_Value[3], m_Value[4], m_Value[5], m_Value[6], m_Value[7],
+ m_Value[8], m_Value[9], m_Value[10], m_Value[11], m_Value[12], m_Value[13], m_Value[14], m_Value[15]
+ );
+
+ ui32_t offset = strlen(str_buf);
+
+ if ( ( m_Value[8] & 0x80 ) == 0 )
+ {
+ // half-swapped UL, use [bbaa9988.ddcc.ffee.00010203.04050607]
+ snprintf(str_buf + offset, IdentBufferLen - offset,
+ "[%02x%02x%02x%02x.%02x%02x.%02x%02x.%02x%02x%02x%02x.%02x%02x%02x%02x]",
+ m_Value[24], m_Value[25], m_Value[26], m_Value[27], m_Value[28], m_Value[29], m_Value[30], m_Value[31],
+ m_Value[16], m_Value[17], m_Value[18], m_Value[19], m_Value[20], m_Value[21], m_Value[22], m_Value[23]
+ );
+ }
+ else
+ {
+ // UUID, use {00112233-4455-6677-8899-aabbccddeeff}
+ snprintf(str_buf + offset, IdentBufferLen - offset,
+ "{%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
+ m_Value[16], m_Value[17], m_Value[18], m_Value[19], m_Value[20], m_Value[21], m_Value[22], m_Value[23],
+ m_Value[24], m_Value[25], m_Value[26], m_Value[27], m_Value[28], m_Value[29], m_Value[30], m_Value[31]
+ );
+ }
+
+ return str_buf;
+}
+
+//
+void
+ASDCP::UUID::GenRandomValue()
+{
+ FortunaRNG RNG;
+ RNG.FillRandom(m_Value, UUIDlen);
+ m_Value[6] &= 0x0f; // clear bits 4-7
+ m_Value[6] |= 0x40; // set UUID version
+ m_Value[8] &= 0x3f; // clear bits 6&7
+ m_Value[8] |= 0x80; // set bit 7
+}
+
+
+//------------------------------------------------------------------------------------------
+//
+
+const ASDCP::MXF::UTF16String&
+ASDCP::MXF::UTF16String::operator=(const char* sz)
+{
+ if ( sz == 0 || *sz == 0 )
+ {
+ m_length = 0;
+ *m_buffer = 0;
+ }
+ else
+ {
+ ui32_t len = xmin((ui32_t)strlen(sz), (IdentBufferLen - 1));
+ m_length = len;
+ memcpy(m_buffer, sz, m_length);
+ m_buffer[m_length] = 0;
+ }
+
+ return *this;
+}
+
+
//
ASDCP::Result_t
-ASDCP::MXF::UTF16String::ReadFrom(ASDCP::MemIOReader& Reader)
+ASDCP::MXF::UTF16String::Unarchive(ASDCP::MemIOReader& Reader)
{
const byte_t* p = Reader.Data() + Reader.Offset();
/// cheating - for all use cases, we know the previous two bytes are the length
@@ -57,7 +174,7 @@ ASDCP::MXF::UTF16String::ReadFrom(ASDCP::MemIOReader& Reader)
//
ASDCP::Result_t
-ASDCP::MXF::UTF16String::WriteTo(ASDCP::MemIOWriter& Writer)
+ASDCP::MXF::UTF16String::Archive(ASDCP::MemIOWriter& Writer)
{
byte_t* p = Writer.Data() + Writer.Size();
ui32_t i = 0;
@@ -67,9 +184,7 @@ ASDCP::MXF::UTF16String::WriteTo(ASDCP::MemIOWriter& Writer)
for ( i = 0; i < m_length; i++ )
p[(i*2)+1] = m_buffer[i];
- m_buffer[i] = 0;
-
- Writer.AddOffset(m_length*2);
+ Writer.AddOffset(m_length * 2 );
return RESULT_OK;
}
@@ -77,6 +192,242 @@ ASDCP::MXF::UTF16String::WriteTo(ASDCP::MemIOWriter& Writer)
//------------------------------------------------------------------------------------------
//
+#ifdef WIN32
+
+#define TIMESTAMP_TO_SYSTIME(ts, t) \
+ (t)->wYear = (ts).Year; /* year */ \
+ (t)->wMonth = (ts).Month; /* month of year (1 - 12) */ \
+ (t)->wDay = (ts).Day; /* day of month (1 - 31) */ \
+ (t)->wHour = (ts).Hour; /* hours (0 - 23) */ \
+ (t)->wMinute = (ts).Minute; /* minutes (0 - 59) */ \
+ (t)->wSecond = (ts).Second; /* seconds (0 - 60) */ \
+ (t)->wDayOfWeek = 0; \
+ (t)->wMilliseconds = ((ts).Tick * 4);
+
+#define SYSTIME_TO_TIMESTAMP(t, ts) \
+ (ts).Year = (t)->wYear; /* year */ \
+ (ts).Month = (t)->wMonth; /* month of year (1 - 12) */ \
+ (ts).Day = (t)->wDay; /* day of month (1 - 31) */ \
+ (ts).Hour = (t)->wHour; /* hours (0 - 23) */ \
+ (ts).Minute = (t)->wMinute; /* minutes (0 - 59) */ \
+ (ts).Second = (t)->wSecond; /* seconds (0 - 60) */ \
+ (ts).Tick = (t)->wMilliseconds / 4;
+
+//
+ASDCP::MXF::Timestamp::Timestamp() :
+ Year(0), Month(0), Day(0), Hour(0), Minute(0), Second(0), Tick(0)
+{
+ SYSTEMTIME sys_time;
+ GetSystemTime(&sys_time);
+ SYSTIME_TO_TIMESTAMP(&sys_time, *this);
+}
+
+//
+bool
+ASDCP::MXF::Timestamp::operator<(const Timestamp& rhs) const
+{
+ SYSTEMTIME lhst, rhst;
+ FILETIME lft, rft;
+
+ TIMESTAMP_TO_SYSTIME(*this, &lhst);
+ TIMESTAMP_TO_SYSTIME(rhs, &rhst);
+ SystemTimeToFileTime(&lhst, &lft);
+ SystemTimeToFileTime(&rhst, &rft);
+ return ( CompareFileTime(&lft, &rft) == -1 );
+}
+
+inline ui64_t
+seconds_to_ns100(ui32_t seconds)
+{
+ return ((ui64_t)seconds * 10000000);
+}
+
+//
+void
+ASDCP::MXF::Timestamp::AddDays(i32_t days)
+{
+ SYSTEMTIME current_st;
+ FILETIME current_ft;
+ ULARGE_INTEGER current_ul;
+
+ if ( days != 0 )
+ {
+ TIMESTAMP_TO_SYSTIME(*this, &current_st);
+ SystemTimeToFileTime(&current_st, &current_ft);
+ memcpy(&current_ul, &current_ft, sizeof(current_ul));
+ current_ul.QuadPart += ( seconds_to_ns100(86400) * (ui64_t)days );
+ memcpy(&current_ft, &current_ul, sizeof(current_ft));
+ FileTimeToSystemTime(&current_ft, &current_st);
+ SYSTIME_TO_TIMESTAMP(&current_st, *this);
+ }
+}
+
+//
+void
+ASDCP::MXF::Timestamp::AddHours(i32_t hours)
+{
+ SYSTEMTIME current_st;
+ FILETIME current_ft;
+ ULARGE_INTEGER current_ul;
+
+ if ( hours != 0 )
+ {
+ TIMESTAMP_TO_SYSTIME(*this, &current_st);
+ SystemTimeToFileTime(&current_st, &current_ft);
+ memcpy(&current_ul, &current_ft, sizeof(current_ul));
+ current_ul.QuadPart += ( seconds_to_ns100(3600) * (ui64_t)hours );
+ memcpy(&current_ft, &current_ul, sizeof(current_ft));
+ FileTimeToSystemTime(&current_ft, &current_st);
+ SYSTIME_TO_TIMESTAMP(&current_st, *this);
+ }
+}
+
+#else // WM_WIN32
+
+#include <time.h>
+
+#define TIMESTAMP_TO_TM(ts, t) \
+ (t)->tm_year = (ts).Year - 1900; /* year - 1900 */ \
+ (t)->tm_mon = (ts).Month - 1; /* month of year (0 - 11) */ \
+ (t)->tm_mday = (ts).Day; /* day of month (1 - 31) */ \
+ (t)->tm_hour = (ts).Hour; /* hours (0 - 23) */ \
+ (t)->tm_min = (ts).Minute; /* minutes (0 - 59) */ \
+ (t)->tm_sec = (ts).Second; /* seconds (0 - 60) */
+
+#define TM_TO_TIMESTAMP(t, ts) \
+ (ts).Year = (t)->tm_year + 1900; /* year - 1900 */ \
+ (ts).Month = (t)->tm_mon + 1; /* month of year (0 - 11) */ \
+ (ts).Day = (t)->tm_mday; /* day of month (1 - 31) */ \
+ (ts).Hour = (t)->tm_hour; /* hours (0 - 23) */ \
+ (ts).Minute = (t)->tm_min; /* minutes (0 - 59) */ \
+ (ts).Second = (t)->tm_sec; /* seconds (0 - 60) */
+
+//
+ASDCP::MXF::Timestamp::Timestamp() :
+ Year(0), Month(0), Day(0), Hour(0), Minute(0), Second(0)
+{
+ time_t t_now = time(0);
+ struct tm* now = gmtime(&t_now);
+ TM_TO_TIMESTAMP(now, *this);
+}
+
+//
+bool
+ASDCP::MXF::Timestamp::operator<(const Timestamp& rhs) const
+{
+ struct tm lhtm, rhtm;
+ TIMESTAMP_TO_TM(*this, &lhtm);
+ TIMESTAMP_TO_TM(rhs, &rhtm);
+ return ( timegm(&lhtm) < timegm(&rhtm) );
+}
+
+//
+void
+ASDCP::MXF::Timestamp::AddDays(i32_t days)
+{
+ struct tm current;
+
+ if ( days != 0 )
+ {
+ TIMESTAMP_TO_TM(*this, &current);
+ time_t adj_time = timegm(&current);
+ adj_time += 86400 * days;
+ struct tm* now = gmtime(&adj_time);
+ TM_TO_TIMESTAMP(now, *this);
+ }
+}
+
+//
+void
+ASDCP::MXF::Timestamp::AddHours(i32_t hours)
+{
+ struct tm current;
+
+ if ( hours != 0 )
+ {
+ TIMESTAMP_TO_TM(*this, &current);
+ time_t adj_time = timegm(&current);
+ adj_time += 3600 * hours;
+ struct tm* now = gmtime(&adj_time);
+ TM_TO_TIMESTAMP(now, *this);
+ }
+}
+
+#endif // WM_WIN32
+
+
+ASDCP::MXF::Timestamp::Timestamp(const Timestamp& rhs)
+{
+ Year = rhs.Year;
+ Month = rhs.Month;
+ Day = rhs.Day;
+ Hour = rhs.Hour;
+ Minute = rhs.Minute;
+ Second = rhs.Second;
+}
+
+ASDCP::MXF::Timestamp::~Timestamp()
+{
+}
+
+//
+const ASDCP::MXF::Timestamp&
+ASDCP::MXF::Timestamp::operator=(const Timestamp& rhs)
+{
+ Year = rhs.Year;
+ Month = rhs.Month;
+ Day = rhs.Day;
+ Hour = rhs.Hour;
+ Minute = rhs.Minute;
+ Second = rhs.Second;
+ return *this;
+}
+
+//
+bool
+ASDCP::MXF::Timestamp::operator==(const Timestamp& rhs) const
+{
+ if ( Year == rhs.Year
+ && Month == rhs.Month
+ && Day == rhs.Day
+ && Hour == rhs.Hour
+ && Minute == rhs.Minute
+ && Second == rhs.Second )
+ return true;
+
+ return false;
+}
+
+//
+bool
+ASDCP::MXF::Timestamp::operator!=(const Timestamp& rhs) const
+{
+ if ( Year != rhs.Year
+ || Month != rhs.Month
+ || Day != rhs.Day
+ || Hour != rhs.Hour
+ || Minute != rhs.Minute
+ || Second != rhs.Second )
+ return true;
+
+ return false;
+}
+
+//
+const char*
+ASDCP::MXF::Timestamp::ToString(char* str_buf) const
+{
+ // 2004-05-01 13:20:00.000
+ snprintf(str_buf, IntBufferLen,
+ "%04hu-%02hu-%02hu %02hu:%02hu:%02hu.000",
+ Year, Month, Day, Hour, Minute, Second, Tick);
+
+ return str_buf;
+}
+
+//------------------------------------------------------------------------------------------
+//
+
ASDCP::MXF::TLVReader::TLVReader(const byte_t* p, ui32_t c, IPrimerLookup* PrimerLookup) :
MemIOReader(p, c), m_Lookup(PrimerLookup)
{
@@ -116,7 +467,7 @@ ASDCP::MXF::TLVReader::FindTL(const MDDEntry& Entry)
{
if ( m_Lookup == 0 )
{
- fprintf(stderr, "No Lookup service\n");
+ DefaultLogSink().Error("No Lookup service\n");
return false;
}
@@ -154,7 +505,7 @@ ASDCP::MXF::TLVReader::ReadObject(const MDDEntry& Entry, IArchive* Object)
ASDCP_TEST_NULL(Object);
if ( FindTL(Entry) )
- return Object->ReadFrom(*this);
+ return Object->Unarchive(*this);
return RESULT_FALSE;
}
@@ -220,15 +571,15 @@ ASDCP::MXF::TLVWriter::TLVWriter(byte_t* p, ui32_t c, IPrimerLookup* PrimerLooku
ASDCP::Result_t
ASDCP::MXF::TLVWriter::WriteTag(const MDDEntry& Entry)
{
- TagValue TmpTag;
-
if ( m_Lookup == 0 )
{
DefaultLogSink().Error("No Primer object available\n");
return RESULT_FAIL;
}
- if ( m_Lookup->InsertTag(Entry.ul, TmpTag) != RESULT_OK )
+ TagValue TmpTag;
+
+ if ( m_Lookup->InsertTag(Entry, TmpTag) != RESULT_OK )
{
DefaultLogSink().Error("No tag for entry %s\n", Entry.name);
return RESULT_FAIL;
@@ -256,7 +607,7 @@ ASDCP::MXF::TLVWriter::WriteObject(const MDDEntry& Entry, IArchive* Object)
if ( ASDCP_SUCCESS(result) )
{
ui32_t before = Size();
- result = Object->WriteTo(*this);
+ result = Object->Archive(*this);
if ( ASDCP_SUCCESS(result) )
i2p<ui16_t>(ASDCP_i16_BE( Size() - before), l_p);
@@ -283,7 +634,7 @@ ASDCP::MXF::TLVWriter::WriteUi16(const MDDEntry& Entry, ui16_t* value)
ASDCP_TEST_NULL(value);
Result_t result = WriteTag(Entry);
if ( ASDCP_SUCCESS(result) ) MemIOWriter::WriteUi16BE(sizeof(ui16_t));
- if ( ASDCP_SUCCESS(result) ) MemIOWriter::WriteUi8(*value);
+ if ( ASDCP_SUCCESS(result) ) MemIOWriter::WriteUi16BE(*value);
return result;
}
@@ -294,7 +645,7 @@ ASDCP::MXF::TLVWriter::WriteUi32(const MDDEntry& Entry, ui32_t* value)
ASDCP_TEST_NULL(value);
Result_t result = WriteTag(Entry);
if ( ASDCP_SUCCESS(result) ) MemIOWriter::WriteUi16BE(sizeof(ui32_t));
- if ( ASDCP_SUCCESS(result) ) MemIOWriter::WriteUi8(*value);
+ if ( ASDCP_SUCCESS(result) ) MemIOWriter::WriteUi32BE(*value);
return result;
}
@@ -305,10 +656,10 @@ ASDCP::MXF::TLVWriter::WriteUi64(const MDDEntry& Entry, ui64_t* value)
ASDCP_TEST_NULL(value);
Result_t result = WriteTag(Entry);
if ( ASDCP_SUCCESS(result) ) MemIOWriter::WriteUi16BE(sizeof(ui64_t));
- if ( ASDCP_SUCCESS(result) ) MemIOWriter::WriteUi8(*value);
+ if ( ASDCP_SUCCESS(result) ) MemIOWriter::WriteUi64BE(*value);
return result;
}
//
-// end
+// end MXFTypes.cpp
//