X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=src%2Fh__Reader.cpp;h=268f3086624f74e038484cd68bfdaea2cb2bccef;hb=bfedf725dac9d13f3a02fe69f45c302ab29d2b1e;hp=4c1cf12082e839685ca41807068032fdf1a769f9;hpb=6e23666cb6184999efc74577cfb1b524181ba5df;p=asdcplib.git diff --git a/src/h__Reader.cpp b/src/h__Reader.cpp index 4c1cf12..268f308 100755 --- a/src/h__Reader.cpp +++ b/src/h__Reader.cpp @@ -1,5 +1,5 @@ /* -Copyright (c) 2004-2005, John Hurst +Copyright (c) 2004-2006, John Hurst All rights reserved. Redistribution and use in source and binary forms, with or without @@ -31,8 +31,6 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "AS_DCP_internal.h" #include "KLV.h" -#include "MDD.h" -#include using namespace ASDCP; using namespace ASDCP::MXF; @@ -58,10 +56,19 @@ ASDCP::h__Reader::Close() // Result_t -ASDCP::h__Reader::InitInfo(WriterInfo& Info) +ASDCP::h__Reader::InitInfo() { InterchangeObject* Object; + m_Info.LabelSetType = LS_MXF_UNKNOWN; + UL OPAtomUL(Dict::ul(MDD_OPAtom)); + UL Interop_OPAtomUL(Dict::ul(MDD_MXFInterop_OPAtom)); + + if ( m_HeaderPart.OperationalPattern == Interop_OPAtomUL ) + m_Info.LabelSetType = LS_MXF_INTEROP; + else if ( m_HeaderPart.OperationalPattern == OPAtomUL ) + m_Info.LabelSetType = LS_MXF_SMPTE; + // Identification Result_t result = m_HeaderPart.GetMDObjectByType(OBJ_TYPE_ARGS(Identification), &Object); @@ -75,7 +82,7 @@ ASDCP::h__Reader::InitInfo(WriterInfo& Info) if( ASDCP_SUCCESS(result) ) { SourcePackage* SP = (SourcePackage*)Object; - memcpy(Info.AssetUUID, SP->PackageUID.Value() + 16, UUIDlen); + memcpy(m_Info.AssetUUID, SP->PackageUID.Value() + 16, UUIDlen); } // optional CryptographicContext @@ -95,37 +102,24 @@ ASDCP::h__Reader::InitInfo(WriterInfo& Info) Result_t ASDCP::h__Reader::OpenMXFRead(const char* filename) { + m_LastPosition = 0; Result_t result = m_File.OpenRead(filename); if ( ASDCP_SUCCESS(result) ) result = m_HeaderPart.InitFromFile(m_File); - // OP-Atom states that there will be either two or three partitions, - // one closed header and one closed footer with an optional body - ui32_t test_s = m_HeaderPart.m_RIP.PairArray.size(); - - if ( test_s < 2 || test_s > 3 ) - { - DefaultLogSink().Error("RIP count is not 2 or 3: %lu\n", test_s); - return RESULT_FORMAT; - } - - // it really OP-Atom? - // MDObject* OpPattern = GetMDObjectByType("OperationalPattern"); - // TODO: check the label - // if this is a three partition file, go to the body // partition and read off the partition pack - if ( test_s == 3 ) + if ( m_HeaderPart.m_RIP.PairArray.size() == 3 ) { - DefaultLogSink().Error("RIP count is 3: must write code...\n"); - return RESULT_FORMAT; + Array::iterator r_i = m_HeaderPart.m_RIP.PairArray.begin(); + r_i++; + m_File.Seek((*r_i).ByteOffset); + + result = m_BodyPart.InitFromFile(m_File); } - // TODO: check the partition pack to make sure it is - // really a body with a single essence container m_EssenceStart = m_File.Tell(); - return RESULT_OK; } @@ -145,9 +139,42 @@ ASDCP::h__Reader::InitMXFIndex() result = m_FooterPart.InitFromFile(m_File); } + if ( ASDCP_SUCCESS(result) ) + m_File.Seek(m_EssenceStart); + return result; } +// +class KLReader : public ASDCP::KLVPacket +{ + ASDCP_NO_COPY_CONSTRUCT(KLReader); + byte_t m_KeyBuf[32]; + +public: + KLReader() {} + ~KLReader() {} + + inline const byte_t* Key() { return m_KeyBuf; } + inline const ui64_t Length() { return m_ValueLength; } + inline const ui64_t KLLength() { return m_KLLength; } + + Result_t ReadKLFromFile(Kumu::FileReader& Reader) + { + ui32_t read_count; + ui32_t header_length = SMPTE_UL_LENGTH + MXF_BER_LENGTH; + Result_t result = Reader.Read(m_KeyBuf, header_length, &read_count); + + if ( read_count != header_length ) + return RESULT_READFAIL; + + if ( ASDCP_SUCCESS(result) ) + result = InitFromBuffer(m_KeyBuf, header_length); + + return result; + } +}; + // standard method of reading a plaintext or encrypted frame Result_t @@ -164,10 +191,15 @@ ASDCP::h__Reader::ReadEKLVPacket(ui32_t FrameNum, ASDCP::FrameBuffer& FrameBuf, } // get frame position and go read the frame's key and length - ASDCP::KLVReader Reader; - ASDCP::fpos_t FilePosition = m_EssenceStart + TmpEntry.StreamOffset; + Result_t result = RESULT_OK; + KLReader Reader; + Kumu::fpos_t FilePosition = m_EssenceStart + TmpEntry.StreamOffset; - Result_t result = m_File.Seek(FilePosition); + if ( FilePosition != m_LastPosition ) + { + m_LastPosition = FilePosition; + result = m_File.Seek(FilePosition); + } if ( ASDCP_SUCCESS(result) ) result = Reader.ReadKLFromFile(m_File); @@ -176,11 +208,11 @@ ASDCP::h__Reader::ReadEKLVPacket(ui32_t FrameNum, ASDCP::FrameBuffer& FrameBuf, return result; UL Key(Reader.Key()); - UL InteropRef(CryptEssenceUL_Data); - UL SMPTERef(CryptEssenceUL_Data); ui64_t PacketLength = Reader.Length(); + m_LastPosition = m_LastPosition + Reader.KLLength() + PacketLength; - if ( Key == InteropRef || Key == SMPTERef ) + if ( memcmp(Key.Value(), Dict::ul(MDD_CryptEssence), Key.Size() - 1) == 0 // ignore the stream numbers + || memcmp(Key.Value(), Dict::ul(MDD_MXFInterop_CryptEssence), Key.Size() - 1) == 0 ) { if ( ! m_Info.EncryptedEssence ) { @@ -208,7 +240,7 @@ ASDCP::h__Reader::ReadEKLVPacket(ui32_t FrameNum, ASDCP::FrameBuffer& FrameBuf, byte_t* ess_p = m_CtFrameBuf.Data(); // read context ID length - if ( ! read_test_BER(&ess_p, UUIDlen) ) + if ( ! Kumu::read_test_BER(&ess_p, UUIDlen) ) return RESULT_FORMAT; // test the context ID @@ -220,24 +252,34 @@ ASDCP::h__Reader::ReadEKLVPacket(ui32_t FrameNum, ASDCP::FrameBuffer& FrameBuf, ess_p += UUIDlen; // read PlaintextOffset length - if ( ! read_test_BER(&ess_p, sizeof(ui64_t)) ) + if ( ! Kumu::read_test_BER(&ess_p, sizeof(ui64_t)) ) return RESULT_FORMAT; - ui32_t PlaintextOffset = (ui32_t)ASDCP_i64_BE(cp2i(ess_p)); + ui32_t PlaintextOffset = (ui32_t)KM_i64_BE(Kumu::cp2i(ess_p)); ess_p += sizeof(ui64_t); // read essence UL length - if ( ! read_test_BER(&ess_p, klv_key_size) ) + if ( ! Kumu::read_test_BER(&ess_p, SMPTE_UL_LENGTH) ) return RESULT_FORMAT; - // TODO: test essence UL - ess_p += klv_key_size; + // test essence UL + if ( memcmp(ess_p, EssenceUL, SMPTE_UL_LENGTH - 1) != 0 ) // ignore the stream number + { + char strbuf[IntBufferLen]; + const MDDEntry* Entry = Dict::FindUL(Key.Value()); + if ( Entry == 0 ) + DefaultLogSink().Warn("Unexpected Essence UL found: %s.\n", Key.EncodeString(strbuf, IntBufferLen)); + else + DefaultLogSink().Warn("Unexpected Essence UL found: %s.\n", Entry->name); + return RESULT_FORMAT; + } + ess_p += SMPTE_UL_LENGTH; // read SourceLength length - if ( ! read_test_BER(&ess_p, sizeof(ui64_t)) ) + if ( ! Kumu::read_test_BER(&ess_p, sizeof(ui64_t)) ) return RESULT_FORMAT; - ui32_t SourceLength = (ui32_t)ASDCP_i64_BE(cp2i(ess_p)); + ui32_t SourceLength = (ui32_t)KM_i64_BE(Kumu::cp2i(ess_p)); ess_p += sizeof(ui64_t); assert(SourceLength); @@ -250,7 +292,7 @@ ASDCP::h__Reader::ReadEKLVPacket(ui32_t FrameNum, ASDCP::FrameBuffer& FrameBuf, ui32_t esv_length = calc_esv_length(SourceLength, PlaintextOffset); // read ESV length - if ( ! read_test_BER(&ess_p, esv_length) ) + if ( ! Kumu::read_test_BER(&ess_p, esv_length) ) { DefaultLogSink().Error("read_test_BER did not return %lu\n", esv_length); return RESULT_FORMAT; @@ -295,7 +337,7 @@ ASDCP::h__Reader::ReadEKLVPacket(ui32_t FrameNum, ASDCP::FrameBuffer& FrameBuf, FrameBuf.PlaintextOffset(PlaintextOffset); } } - else if ( Key == EssenceUL ) + else if ( memcmp(Key.Value(), EssenceUL, Key.Size() - 1) == 0 ) // ignore the stream number { // read plaintext frame if ( FrameBuf.Capacity() < PacketLength ) { @@ -328,7 +370,12 @@ ASDCP::h__Reader::ReadEKLVPacket(ui32_t FrameNum, ASDCP::FrameBuffer& FrameBuf, } else { - DefaultLogSink().Error("Unexpected UL found.\n"); + char strbuf[IntBufferLen]; + const MDDEntry* Entry = Dict::FindUL(Key.Value()); + if ( Entry == 0 ) + DefaultLogSink().Warn("Unexpected Essence UL found: %s.\n", Key.EncodeString(strbuf, IntBufferLen)); + else + DefaultLogSink().Warn("Unexpected Essence UL found: %s.\n", Entry->name); return RESULT_FORMAT; }