X-Git-Url: https://git.carlh.net/gitweb/?a=blobdiff_plain;f=src%2FAS_DCP_MPEG2.cpp;h=8353ea4f1e7edae62bbd7df966291a63ba5b28dd;hb=7f3035721a09a68106454a53be4fe7f967543195;hp=ea7ed74894630533adf1b794f0935e79203aa4a1;hpb=99f3c9bd7e314ed2342598ad0e2357c68c79e732;p=asdcplib.git diff --git a/src/AS_DCP_MPEG2.cpp b/src/AS_DCP_MPEG2.cpp index ea7ed74..8353ea4 100755 --- a/src/AS_DCP_MPEG2.cpp +++ b/src/AS_DCP_MPEG2.cpp @@ -1,5 +1,5 @@ /* -Copyright (c) 2004-2012, John Hurst +Copyright (c) 2004-2013, John Hurst All rights reserved. Redistribution and use in source and binary forms, with or without @@ -36,10 +36,6 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. //------------------------------------------------------------------------------------------ -static const ASDCP::Dictionary *sg_dict = &DefaultSMPTEDict(); -static MXF::OPAtomHeader sg_OPAtomHeader(sg_dict); -static MXF::OPAtomIndexFooter sg_OPAtomIndexFooter(sg_dict); - static std::string MPEG_PACKAGE_LABEL = "File Package: SMPTE 381M frame wrapping of MPEG2 video elementary stream"; static std::string PICT_DEF_LABEL = "Picture Track"; @@ -66,7 +62,7 @@ MD_to_MPEG2_VDesc(MXF::MPEG2VideoDescriptor* VDescObj, MPEG2::VideoDescriptor& V VDesc.ColorSiting = VDescObj->ColorSiting; VDesc.CodedContentType = VDescObj->CodedContentType; - VDesc.LowDelay = VDescObj->LowDelay == 0 ? false : true; + VDesc.LowDelay = VDescObj->LowDelay.get() == 0 ? false : true; VDesc.BitRate = VDescObj->BitRate; VDesc.ProfileAndLevel = VDescObj->ProfileAndLevel; return RESULT_OK; @@ -164,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(); @@ -172,9 +168,9 @@ 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() {} - Result_t OpenRead(const char*); + h__Reader(const Dictionary& d) : ASDCP::h__ASDCPReader(d) {} + virtual ~h__Reader() {} + Result_t OpenRead(const std::string&); Result_t ReadFrame(ui32_t, FrameBuffer&, AESDecContext*, HMACContext*); Result_t ReadFrameGOPStart(ui32_t, FrameBuffer&, AESDecContext*, HMACContext*); Result_t FindFrameGOPStart(ui32_t, ui32_t&); @@ -185,26 +181,26 @@ public: // // ASDCP::Result_t -ASDCP::MPEG2::MXFReader::h__Reader::OpenRead(const char* filename) +ASDCP::MPEG2::MXFReader::h__Reader::OpenRead(const std::string& filename) { Result_t result = OpenMXFRead(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; } @@ -239,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; @@ -260,7 +256,7 @@ ASDCP::MPEG2::MXFReader::h__Reader::FrameType(ui32_t FrameNum, FrameType_t& type // 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; @@ -287,7 +283,7 @@ ASDCP::MPEG2::MXFReader::h__Reader::ReadFrame(ui32_t FrameNum, FrameBuffer& Fram return result; IndexTableSegment::IndexEntry TmpEntry; - m_FooterPart.Lookup(FrameNum, TmpEntry); + m_IndexAccess.Lookup(FrameNum, TmpEntry); switch ( ( TmpEntry.Flags >> 4 ) & 0x03 ) { @@ -337,16 +333,21 @@ 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::OPAtomHeader& -ASDCP::MPEG2::MXFReader::OPAtomHeader() +ASDCP::MXF::OP1aHeader& +ASDCP::MPEG2::MXFReader::OP1aHeader() { if ( m_Reader.empty() ) - return sg_OPAtomHeader; + { + assert(g_OP1aHeader); + return *g_OP1aHeader; + } return m_Reader->m_HeaderPart; } @@ -358,15 +359,33 @@ ASDCP::MXF::OPAtomIndexFooter& ASDCP::MPEG2::MXFReader::OPAtomIndexFooter() { if ( m_Reader.empty() ) - return sg_OPAtomIndexFooter; + { + assert(g_OPAtomIndexFooter); + return *g_OPAtomIndexFooter; + } - return m_Reader->m_FooterPart; + 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 // operation cannot be completed. ASDCP::Result_t -ASDCP::MPEG2::MXFReader::OpenRead(const char* filename) const +ASDCP::MPEG2::MXFReader::OpenRead(const std::string& filename) const { return m_Reader->OpenRead(filename); } @@ -383,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, @@ -449,7 +475,7 @@ 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); } // @@ -479,7 +505,7 @@ ASDCP::MPEG2::MXFReader::FrameType(ui32_t FrameNum, FrameType_t& type) const //------------------------------------------------------------------------------------------ // -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(); @@ -489,13 +515,13 @@ 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 OpenWrite(const std::string&, ui32_t HeaderSize); Result_t SetSourceStream(const VideoDescriptor&); Result_t WriteFrame(const FrameBuffer&, AESEncContext* = 0, HMACContext* = 0); Result_t Finalize(); @@ -505,7 +531,7 @@ public: // Open the file for writing. The file must not exist. Returns error if // the operation cannot be completed. ASDCP::Result_t -ASDCP::MPEG2::MXFWriter::h__Writer::OpenWrite(const char* filename, ui32_t HeaderSize) +ASDCP::MPEG2::MXFWriter::h__Writer::OpenWrite(const std::string& filename, ui32_t HeaderSize) { if ( ! m_State.Test_BEGIN() ) return RESULT_STATE; @@ -542,11 +568,11 @@ ASDCP::MPEG2::MXFWriter::h__Writer::SetSourceStream(const VideoDescriptor& VDesc if ( ASDCP_SUCCESS(result) ) { - ui32_t TCFrameRate = ( m_VDesc.EditRate == EditRate_23_98 ) ? 24 : m_VDesc.EditRate.Numerator; + m_FooterPart.SetDeltaParams(IndexTableSegment::DeltaEntry(-1, 0, 0)); - result = WriteMXFHeader(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, TCFrameRate); + result = WriteASDCPHeader(MPEG_PACKAGE_LABEL, UL(m_Dict->ul(MDD_MPEG2_VESWrappingFrame)), + 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; @@ -623,7 +649,7 @@ ASDCP::MPEG2::MXFWriter::h__Writer::Finalize() m_State.Goto_FINAL(); - return WriteMXFFooter(); + return WriteASDCPFooter(); } @@ -642,11 +668,14 @@ ASDCP::MPEG2::MXFWriter::~MXFWriter() // Warning: direct manipulation of MXF structures can interfere // with the normal operation of the wrapper. Caveat emptor! // -ASDCP::MXF::OPAtomHeader& -ASDCP::MPEG2::MXFWriter::OPAtomHeader() +ASDCP::MXF::OP1aHeader& +ASDCP::MPEG2::MXFWriter::OP1aHeader() { if ( m_Writer.empty() ) - return sg_OPAtomHeader; + { + assert(g_OP1aHeader); + return *g_OP1aHeader; + } return m_Writer->m_HeaderPart; } @@ -658,15 +687,33 @@ ASDCP::MXF::OPAtomIndexFooter& ASDCP::MPEG2::MXFWriter::OPAtomIndexFooter() { if ( m_Writer.empty() ) - return sg_OPAtomIndexFooter; + { + 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. ASDCP::Result_t -ASDCP::MPEG2::MXFWriter::OpenWrite(const char* filename, const WriterInfo& Info, +ASDCP::MPEG2::MXFWriter::OpenWrite(const std::string& filename, const WriterInfo& Info, const VideoDescriptor& VDesc, ui32_t HeaderSize) { if ( Info.LabelSetType == LS_MXF_SMPTE )