X-Git-Url: https://git.carlh.net/gitweb/?a=blobdiff_plain;f=src%2Fh__Reader.cpp;h=d329e603bc474bed6023f9a4da15c4060b39fe4c;hb=6159b54a6ea46408a71c74b7c0a999c9ff5449e5;hp=e958e345d2249aacc5cf3e3edf456e0382686d1b;hpb=dde89765744dad9a6b9d13126092d9bfc2dbc0d7;p=asdcplib.git diff --git a/src/h__Reader.cpp b/src/h__Reader.cpp index e958e34..d329e60 100755 --- a/src/h__Reader.cpp +++ b/src/h__Reader.cpp @@ -108,19 +108,23 @@ ASDCP::h__Reader::OpenMXFRead(const char* filename) if ( ASDCP_SUCCESS(result) ) result = m_HeaderPart.InitFromFile(m_File); - // if this is a three partition file, go to the body - // partition and read off the partition pack - if ( m_HeaderPart.m_RIP.PairArray.size() == 3 ) + if ( ASDCP_SUCCESS(result) ) { - DefaultLogSink().Error("RIP count is 3: must write code...\n"); - return RESULT_FORMAT; - } - // TODO: check the partition pack to make sure it is - // really a body with a single essence container + // if this is a three partition file, go to the body + // partition and read the partition pack + if ( m_HeaderPart.m_RIP.PairArray.size() > 2 ) + { + Array::iterator r_i = m_HeaderPart.m_RIP.PairArray.begin(); + r_i++; + m_File.Seek((*r_i).ByteOffset); + + result = m_BodyPart.InitFromFile(m_File); + } - m_EssenceStart = m_File.Tell(); + m_EssenceStart = m_File.Tell(); + } - return RESULT_OK; + return result; } @@ -146,54 +150,42 @@ ASDCP::h__Reader::InitMXFIndex() } // -class KLReader : public ASDCP::KLVPacket +Result_t +ASDCP::KLReader::ReadKLFromFile(Kumu::FileReader& Reader) { - ASDCP_NO_COPY_CONSTRUCT(KLReader); - byte_t m_KeyBuf[32]; - -public: - KLReader() {} - ~KLReader() {} + 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); - 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(ASDCP::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) ) + { + if ( read_count != header_length ) + result = RESULT_READFAIL; - if ( ASDCP_SUCCESS(result) ) - result = InitFromBuffer(m_KeyBuf, header_length); - - return result; - } -}; + else + result = InitFromBuffer(m_KeyBuf, header_length); + } + return result; +} // standard method of reading a plaintext or encrypted frame Result_t -ASDCP::h__Reader::ReadEKLVPacket(ui32_t FrameNum, ASDCP::FrameBuffer& FrameBuf, - const byte_t* EssenceUL, AESDecContext* Ctx, HMACContext* HMAC) +ASDCP::h__Reader::ReadEKLVFrame(ui32_t FrameNum, ASDCP::FrameBuffer& FrameBuf, + const byte_t* EssenceUL, AESDecContext* Ctx, HMACContext* HMAC) { // look up frame index node IndexTableSegment::IndexEntry TmpEntry; if ( ASDCP_FAILURE(m_FooterPart.Lookup(FrameNum, TmpEntry)) ) { - DefaultLogSink().Error("Frame value out of range: %lu\n", FrameNum); + DefaultLogSink().Error("Frame value out of range: %u\n", FrameNum); return RESULT_RANGE; } // get frame position and go read the frame's key and length + Kumu::fpos_t FilePosition = m_EssenceStart + TmpEntry.StreamOffset; Result_t result = RESULT_OK; - KLReader Reader; - ASDCP::fpos_t FilePosition = m_EssenceStart + TmpEntry.StreamOffset; if ( FilePosition != m_LastPosition ) { @@ -201,19 +193,29 @@ ASDCP::h__Reader::ReadEKLVPacket(ui32_t FrameNum, ASDCP::FrameBuffer& FrameBuf, result = m_File.Seek(FilePosition); } - if ( ASDCP_SUCCESS(result) ) - result = Reader.ReadKLFromFile(m_File); + if( ASDCP_SUCCESS(result) ) + result = ReadEKLVPacket(FrameNum, FrameNum + 1, FrameBuf, EssenceUL, Ctx, HMAC); + + return result; +} + + +Result_t +ASDCP::h__Reader::ReadEKLVPacket(ui32_t FrameNum, ui32_t SequenceNum, ASDCP::FrameBuffer& FrameBuf, + const byte_t* EssenceUL, AESDecContext* Ctx, HMACContext* HMAC) +{ + KLReader Reader; + Result_t result = Reader.ReadKLFromFile(m_File); if ( ASDCP_FAILURE(result) ) return result; UL Key(Reader.Key()); - UL CryptEssenceUL(Dict::ul(MDD_CryptEssence)); - UL InteropCryptEssenceUL(Dict::ul(MDD_MXFInterop_CryptEssence)); ui64_t PacketLength = Reader.Length(); m_LastPosition = m_LastPosition + Reader.KLLength() + PacketLength; - if ( Key == InteropCryptEssenceUL || Key == CryptEssenceUL ) + 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 ) { @@ -222,9 +224,11 @@ ASDCP::h__Reader::ReadEKLVPacket(ui32_t FrameNum, ASDCP::FrameBuffer& FrameBuf, } // read encrypted triplet value into internal buffer - m_CtFrameBuf.Capacity(PacketLength); + assert(PacketLength <= 0xFFFFFFFFL); + m_CtFrameBuf.Capacity((ui32_t) PacketLength); ui32_t read_count; - result = m_File.Read(m_CtFrameBuf.Data(), PacketLength, &read_count); + result = m_File.Read(m_CtFrameBuf.Data(), (ui32_t) PacketLength, + &read_count); if ( ASDCP_FAILURE(result) ) return result; @@ -235,13 +239,13 @@ ASDCP::h__Reader::ReadEKLVPacket(ui32_t FrameNum, ASDCP::FrameBuffer& FrameBuf, return RESULT_FORMAT; } - m_CtFrameBuf.Size(PacketLength); + m_CtFrameBuf.Size((ui32_t) PacketLength); // should be const but mxflib::ReadBER is not 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 @@ -253,39 +257,49 @@ 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, SMPTE_UL_LENGTH) ) + if ( ! Kumu::read_test_BER(&ess_p, SMPTE_UL_LENGTH) ) return RESULT_FORMAT; - // TODO: test essence UL + // 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); if ( FrameBuf.Capacity() < SourceLength ) { - DefaultLogSink().Error("FrameBuf.Capacity: %lu SourceLength: %lu\n", FrameBuf.Capacity(), SourceLength); + DefaultLogSink().Error("FrameBuf.Capacity: %u SourceLength: %u\n", FrameBuf.Capacity(), SourceLength); return RESULT_SMALLBUF; } 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); + DefaultLogSink().Error("read_test_BER did not return %u\n", esv_length); return RESULT_FORMAT; } @@ -314,13 +328,18 @@ ASDCP::h__Reader::ReadEKLVPacket(ui32_t FrameNum, ASDCP::FrameBuffer& FrameBuf, if ( ASDCP_SUCCESS(result) && m_Info.UsesHMAC && HMAC ) { IntegrityPack IntPack; - result = IntPack.TestValues(TmpWrapper, m_Info.AssetUUID, FrameNum + 1, HMAC); + result = IntPack.TestValues(TmpWrapper, m_Info.AssetUUID, SequenceNum, HMAC); } } else // return ciphertext to caller { if ( FrameBuf.Capacity() < tmp_len ) - return RESULT_SMALLBUF; + { + char intbuf[IntBufferLen]; + DefaultLogSink().Error("FrameBuf.Capacity: %u FrameLength: %s\n", + FrameBuf.Capacity(), ui64sz(PacketLength, intbuf)); + return RESULT_SMALLBUF; + } memcpy(FrameBuf.Data(), ess_p, tmp_len); FrameBuf.Size(tmp_len); @@ -328,19 +347,20 @@ 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 ) { char intbuf[IntBufferLen]; - DefaultLogSink().Error("FrameBuf.Capacity: %lu FrameLength: %s\n", + DefaultLogSink().Error("FrameBuf.Capacity: %u FrameLength: %s\n", FrameBuf.Capacity(), ui64sz(PacketLength, intbuf)); return RESULT_SMALLBUF; } // read the data into the supplied buffer ui32_t read_count; - result = m_File.Read(FrameBuf.Data(), PacketLength, &read_count); + assert(PacketLength <= 0xFFFFFFFFL); + result = m_File.Read(FrameBuf.Data(), (ui32_t) PacketLength, &read_count); if ( ASDCP_FAILURE(result) ) return result; @@ -364,7 +384,7 @@ ASDCP::h__Reader::ReadEKLVPacket(ui32_t FrameNum, ASDCP::FrameBuffer& FrameBuf, char strbuf[IntBufferLen]; const MDDEntry* Entry = Dict::FindUL(Key.Value()); if ( Entry == 0 ) - DefaultLogSink().Warn("Unexpected Essence UL found: %s.\n", Key.ToString(strbuf)); + 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;