X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=src%2FAS_DCP_MPEG2.cpp;h=b10c8b53b995b619df6164e1f2b399ebac3e9960;hb=5584493c50cfa0541398527741253a0db8cdbf18;hp=580c08fd32a33a968f3a042c411be6b049ebb38e;hpb=65a8ec13b66c700b74788d3fc7525e91cf62bab0;p=asdcplib.git diff --git a/src/AS_DCP_MPEG2.cpp b/src/AS_DCP_MPEG2.cpp index 580c08f..b10c8b5 100755 --- a/src/AS_DCP_MPEG2.cpp +++ b/src/AS_DCP_MPEG2.cpp @@ -1,5 +1,5 @@ /* -Copyright (c) 2004-2009, John Hurst +Copyright (c) 2004-2013, John Hurst All rights reserved. Redistribution and use in source and binary forms, with or without @@ -160,7 +160,7 @@ ASDCP::MPEG2::VideoDescriptorDump(const VideoDescriptor& VDesc, FILE* stream) // // hidden, internal implementation of MPEG2 reader -class ASDCP::MPEG2::MXFReader::h__Reader : public ASDCP::h__Reader +class ASDCP::MPEG2::MXFReader::h__Reader : public ASDCP::h__ASDCPReader { ASDCP_NO_COPY_CONSTRUCT(h__Reader); h__Reader(); @@ -168,12 +168,13 @@ class ASDCP::MPEG2::MXFReader::h__Reader : public ASDCP::h__Reader public: VideoDescriptor m_VDesc; // video parameter list - h__Reader(const Dictionary& d) : ASDCP::h__Reader(d) {} - ~h__Reader() {} + h__Reader(const Dictionary& d) : ASDCP::h__ASDCPReader(d) {} + virtual ~h__Reader() {} Result_t OpenRead(const char*); Result_t ReadFrame(ui32_t, FrameBuffer&, AESDecContext*, HMACContext*); Result_t ReadFrameGOPStart(ui32_t, FrameBuffer&, AESDecContext*, HMACContext*); Result_t FindFrameGOPStart(ui32_t, ui32_t&); + Result_t FrameType(ui32_t FrameNum, FrameType_t& type); }; @@ -186,20 +187,20 @@ ASDCP::MPEG2::MXFReader::h__Reader::OpenRead(const char* filename) if( ASDCP_SUCCESS(result) ) { - InterchangeObject* Object; + InterchangeObject* Object = 0; + if ( ASDCP_SUCCESS(m_HeaderPart.GetMDObjectByType(OBJ_TYPE_ARGS(MPEG2VideoDescriptor), &Object)) ) { - assert(Object); + if ( Object == 0 ) + { + DefaultLogSink().Error("MPEG2VideoDescriptor object not found.\n"); + return RESULT_FORMAT; + } + result = MD_to_MPEG2_VDesc((MXF::MPEG2VideoDescriptor*)Object, m_VDesc); } } - if( ASDCP_SUCCESS(result) ) - result = InitMXFIndex(); - - if( ASDCP_SUCCESS(result) ) - result = InitInfo(); - return result; } @@ -234,7 +235,7 @@ ASDCP::MPEG2::MXFReader::h__Reader::FindFrameGOPStart(ui32_t FrameNum, ui32_t& K // look up frame index node IndexTableSegment::IndexEntry TmpEntry; - if ( ASDCP_FAILURE(m_FooterPart.Lookup(FrameNum, TmpEntry)) ) + if ( ASDCP_FAILURE(m_IndexAccess.Lookup(FrameNum, TmpEntry)) ) { DefaultLogSink().Error("Frame value out of range: %u\n", FrameNum); return RESULT_RANGE; @@ -245,6 +246,26 @@ ASDCP::MPEG2::MXFReader::h__Reader::FindFrameGOPStart(ui32_t FrameNum, ui32_t& K return RESULT_OK; } +// +ASDCP::Result_t +ASDCP::MPEG2::MXFReader::h__Reader::FrameType(ui32_t FrameNum, FrameType_t& type) +{ + if ( ! m_File.IsOpen() ) + return RESULT_INIT; + + // look up frame index node + IndexTableSegment::IndexEntry TmpEntry; + + if ( ASDCP_FAILURE(m_IndexAccess.Lookup(FrameNum, TmpEntry)) ) + { + DefaultLogSink().Error("Frame value out of range: %u\n", FrameNum); + return RESULT_RANGE; + } + + type = ( (TmpEntry.Flags & 0x0f) == 3 ) ? FRAME_B : ( (TmpEntry.Flags & 0x0f) == 2 ) ? FRAME_P : FRAME_I; + return RESULT_OK; +} + // // @@ -252,16 +273,17 @@ ASDCP::Result_t ASDCP::MPEG2::MXFReader::h__Reader::ReadFrame(ui32_t FrameNum, FrameBuffer& FrameBuf, AESDecContext* Ctx, HMACContext* HMAC) { + assert(m_Dict); if ( ! m_File.IsOpen() ) return RESULT_INIT; - Result_t result = ReadEKLVFrame(FrameNum, FrameBuf, m_Dict.ul(MDD_MPEG2Essence), Ctx, HMAC); + Result_t result = ReadEKLVFrame(FrameNum, FrameBuf, m_Dict->ul(MDD_MPEG2Essence), Ctx, HMAC); if ( ASDCP_FAILURE(result) ) return result; IndexTableSegment::IndexEntry TmpEntry; - m_FooterPart.Lookup(FrameNum, TmpEntry); + m_IndexAccess.Lookup(FrameNum, TmpEntry); switch ( ( TmpEntry.Flags >> 4 ) & 0x03 ) { @@ -311,6 +333,53 @@ ASDCP::MPEG2::MXFReader::MXFReader() ASDCP::MPEG2::MXFReader::~MXFReader() { + if ( m_Reader && m_Reader->m_File.IsOpen() ) + m_Reader->Close(); +} + +// Warning: direct manipulation of MXF structures can interfere +// with the normal operation of the wrapper. Caveat emptor! +// +ASDCP::MXF::OP1aHeader& +ASDCP::MPEG2::MXFReader::OP1aHeader() +{ + if ( m_Reader.empty() ) + { + assert(g_OP1aHeader); + return *g_OP1aHeader; + } + + return m_Reader->m_HeaderPart; +} + +// Warning: direct manipulation of MXF structures can interfere +// with the normal operation of the wrapper. Caveat emptor! +// +ASDCP::MXF::OPAtomIndexFooter& +ASDCP::MPEG2::MXFReader::OPAtomIndexFooter() +{ + if ( m_Reader.empty() ) + { + assert(g_OPAtomIndexFooter); + return *g_OPAtomIndexFooter; + } + + return m_Reader->m_IndexAccess; +} + +// Warning: direct manipulation of MXF structures can interfere +// with the normal operation of the wrapper. Caveat emptor! +// +ASDCP::MXF::RIP& +ASDCP::MPEG2::MXFReader::RIP() +{ + if ( m_Reader.empty() ) + { + assert(g_RIP); + return *g_RIP; + } + + return m_Reader->m_RIP; } // Open the file for reading. The file must exist. Returns error if the @@ -333,6 +402,13 @@ ASDCP::MPEG2::MXFReader::ReadFrame(ui32_t FrameNum, FrameBuffer& FrameBuf, } +// +ASDCP::Result_t +ASDCP::MPEG2::MXFReader::LocateFrame(ui32_t FrameNum, Kumu::fpos_t& streamOffset, i8_t& temporalOffset, i8_t& keyFrameOffset) const +{ + return m_Reader->LocateFrame(FrameNum, streamOffset, temporalOffset, keyFrameOffset); +} + // ASDCP::Result_t ASDCP::MPEG2::MXFReader::ReadFrameGOPStart(ui32_t FrameNum, FrameBuffer& FrameBuf, @@ -399,14 +475,37 @@ void ASDCP::MPEG2::MXFReader::DumpIndex(FILE* stream) const { if ( m_Reader->m_File.IsOpen() ) - m_Reader->m_FooterPart.Dump(stream); + m_Reader->m_IndexAccess.Dump(stream); +} + +// +ASDCP::Result_t +ASDCP::MPEG2::MXFReader::Close() const +{ + if ( m_Reader && m_Reader->m_File.IsOpen() ) + { + m_Reader->Close(); + return RESULT_OK; + } + + return RESULT_INIT; +} + +// +ASDCP::Result_t +ASDCP::MPEG2::MXFReader::FrameType(ui32_t FrameNum, FrameType_t& type) const +{ + if ( ! m_Reader ) + return RESULT_INIT; + + return m_Reader->FrameType(FrameNum, type); } //------------------------------------------------------------------------------------------ // -class ASDCP::MPEG2::MXFWriter::h__Writer : public ASDCP::h__Writer +class ASDCP::MPEG2::MXFWriter::h__Writer : public ASDCP::h__ASDCPWriter { ASDCP_NO_COPY_CONSTRUCT(h__Writer); h__Writer(); @@ -416,11 +515,11 @@ public: ui32_t m_GOPOffset; byte_t m_EssenceUL[SMPTE_UL_LENGTH]; - h__Writer(const Dictionary& d) : ASDCP::h__Writer(d), m_GOPOffset(0) { + h__Writer(const Dictionary& d) : ASDCP::h__ASDCPWriter(d), m_GOPOffset(0) { memset(m_EssenceUL, 0, SMPTE_UL_LENGTH); } - ~h__Writer(){} + virtual ~h__Writer(){} Result_t OpenWrite(const char*, ui32_t HeaderSize); Result_t SetSourceStream(const VideoDescriptor&); @@ -453,24 +552,27 @@ ASDCP::MPEG2::MXFWriter::h__Writer::OpenWrite(const char* filename, ui32_t Heade ASDCP::Result_t ASDCP::MPEG2::MXFWriter::h__Writer::SetSourceStream(const VideoDescriptor& VDesc) { + assert(m_Dict); if ( ! m_State.Test_INIT() ) return RESULT_STATE; 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); + memcpy(m_EssenceUL, m_Dict->ul(MDD_MPEG2Essence), SMPTE_UL_LENGTH); m_EssenceUL[SMPTE_UL_LENGTH-1] = 1; // first (and only) essence container result = m_State.Goto_READY(); } + if ( ASDCP_SUCCESS(result) ) + { + result = WriteASDCPHeader(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, derive_timecode_rate_from_edit_rate(m_VDesc.EditRate)); + } + return result; } @@ -545,7 +647,7 @@ ASDCP::MPEG2::MXFWriter::h__Writer::Finalize() m_State.Goto_FINAL(); - return WriteMXFFooter(); + return WriteASDCPFooter(); } @@ -561,6 +663,50 @@ ASDCP::MPEG2::MXFWriter::~MXFWriter() { } +// Warning: direct manipulation of MXF structures can interfere +// with the normal operation of the wrapper. Caveat emptor! +// +ASDCP::MXF::OP1aHeader& +ASDCP::MPEG2::MXFWriter::OP1aHeader() +{ + if ( m_Writer.empty() ) + { + assert(g_OP1aHeader); + return *g_OP1aHeader; + } + + return m_Writer->m_HeaderPart; +} + +// Warning: direct manipulation of MXF structures can interfere +// with the normal operation of the wrapper. Caveat emptor! +// +ASDCP::MXF::OPAtomIndexFooter& +ASDCP::MPEG2::MXFWriter::OPAtomIndexFooter() +{ + if ( m_Writer.empty() ) + { + assert(g_OPAtomIndexFooter); + return *g_OPAtomIndexFooter; + } + + return m_Writer->m_FooterPart; +} + +// Warning: direct manipulation of MXF structures can interfere +// with the normal operation of the wrapper. Caveat emptor! +// +ASDCP::MXF::RIP& +ASDCP::MPEG2::MXFWriter::RIP() +{ + if ( m_Writer.empty() ) + { + assert(g_RIP); + return *g_RIP; + } + + return m_Writer->m_RIP; +} // Open the file for writing. The file must not exist. Returns error if // the operation cannot be completed.