X-Git-Url: https://git.carlh.net/gitweb/?a=blobdiff_plain;f=src%2FAS_DCP_MPEG2.cpp;h=b7877b54549be8a135afcd77432619bdc55ae2f8;hb=79912d9558b67fb75dfad8bca29d2db1fa58a769;hp=58013499c81304e06c4289961b19f90243428bdc;hpb=f6382ee078c3d7de2dbf3a01f5624345d2c61e4a;p=asdcplib.git diff --git a/src/AS_DCP_MPEG2.cpp b/src/AS_DCP_MPEG2.cpp index 5801349..b7877b5 100755 --- a/src/AS_DCP_MPEG2.cpp +++ b/src/AS_DCP_MPEG2.cpp @@ -1,5 +1,5 @@ /* -Copyright (c) 2004-2010, John Hurst +Copyright (c) 2004-2013, John Hurst All rights reserved. Redistribution and use in source and binary forms, with or without @@ -62,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; @@ -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,38 +168,39 @@ 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&); + Result_t FrameType(ui32_t FrameNum, FrameType_t& type); }; // // 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; } @@ -234,9 +235,8 @@ 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 +245,25 @@ 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)) ) + { + return RESULT_RANGE; + } + + type = ( (TmpEntry.Flags & 0x0f) == 3 ) ? FRAME_B : ( (TmpEntry.Flags & 0x0f) == 2 ) ? FRAME_P : FRAME_I; + return RESULT_OK; +} + // // @@ -262,7 +281,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 ) { @@ -289,7 +308,7 @@ ASDCP::MPEG2::FrameBuffer::Dump(FILE* stream, ui32_t dump_len) const if ( stream == 0 ) stream = stderr; - fprintf(stream, "Frame: %06u, %c%-2hu, %7u bytes", + fprintf(stream, "Frame: %06u, %c%-2hhu, %7u bytes", m_FrameNumber, FrameTypeChar(m_FrameType), m_TemporalOffset, m_Size); if ( m_GOPStart ) @@ -312,12 +331,59 @@ 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 // 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); } @@ -334,6 +400,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, @@ -400,14 +473,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(); @@ -417,13 +513,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(); @@ -433,7 +529,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; @@ -469,9 +565,13 @@ ASDCP::MPEG2::MXFWriter::h__Writer::SetSourceStream(const VideoDescriptor& VDesc } if ( ASDCP_SUCCESS(result) ) - 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, 24 /* TCFrameRate */); + { + m_FooterPart.SetDeltaParams(IndexTableSegment::DeltaEntry(-1, 0, 0)); + + 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; } @@ -547,7 +647,7 @@ ASDCP::MPEG2::MXFWriter::h__Writer::Finalize() m_State.Goto_FINAL(); - return WriteMXFFooter(); + return WriteASDCPFooter(); } @@ -563,11 +663,55 @@ 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. 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 )