diff options
| author | jhurst <jhurst@cinecert.com> | 2007-05-05 23:51:23 +0000 |
|---|---|---|
| committer | jhurst <> | 2007-05-05 23:51:23 +0000 |
| commit | 27915a74438fcf264d8dfd621dd5e79fa4065813 (patch) | |
| tree | d55b373992b5f2b929840d854e0dd7817b1b5ecc | |
| parent | b072ecf1205c9b00eb8cd8b9370917d52a99927d (diff) | |
new stuff
| -rw-r--r-- | AS_DCP_TimedText.h | 195 | ||||
| -rw-r--r-- | src/AS_DCP_TimedText.cpp | 241 | ||||
| -rw-r--r-- | src/TimedText_Parser.cpp | 131 |
3 files changed, 567 insertions, 0 deletions
diff --git a/AS_DCP_TimedText.h b/AS_DCP_TimedText.h new file mode 100644 index 0000000..ab39528 --- /dev/null +++ b/AS_DCP_TimedText.h @@ -0,0 +1,195 @@ +/* +Copyright (c) 2003-2006, John Hurst +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/*! \file AS_DCP_Subtitle.h + \version $Id$ + \brief experimental AS-DCP subtitle + + Implements Draft S429-5 +*/ + +#include <AS_DCP.h> + + +#ifndef _AS_DCP_SUBTITLE_H_ +#define _AS_DCP_SUBTITLE_H_ + + +namespace ASDCP { + + // + namespace TimedText + { + struct TimedTextDescriptor + { + std::string NamespaceName; + ui32_t ResourceCount; + }; + + // Print debugging information to stream (stderr default) + void DescriptorDump(const TimedTextDescriptor&, FILE* = 0); + + // + class FrameBuffer : public ASDCP::FrameBuffer + { + ASDCP_NO_COPY_CONSTRUCT(FrameBuffer); // TODO: should have copy construct + + protected: + std::string m_MIMEType; + byte_t m_AssetID[UUIDlen]; + + public: + FrameBuffer() { memset(m_AssetID, 0, UUIDlen); } + FrameBuffer(ui32_t size) { Capacity(size); memset(m_AssetID, 0, UUIDlen); } + virtual ~FrameBuffer() {} + + const char* MIMEType() { return m_MIMEType.c_str(); } + void MIMEType(const char* s) { m_MIMEType = s; } + const byte_t* AssetID() { return m_AssetID; } + void AssetID(const byte_t* buf) { memcpy(m_AssetID, buf, UUIDlen); } + + // Print debugging information to stream (stderr default) + void Dump(FILE* = 0, ui32_t dump_bytes = 0) const; + }; + + // + // NOTE: The ReadFrame() and WriteFrame() methods below do not stricly handle "frames". + // They are named for continuity with other AS-DCP lib modules. The methods actually + // handle complete assets, such as XML documents, PNG images and fonts. + // + + // An object which opens and reads a SMPTE 428-7 (or T.I. CineCanvas (TM)) subtitle file. + // The call to OpenRead() reads metadata from the file and populates an internal TimedTextDescriptor + // object. The first call to ReadFrame() returns the XML document. Each subsequent call to + // ReadFrame() reads exactly one resource file (if any) referenced by the XML into the given + // FrameBuffer object. + class DCSubtitleParser + { + class h__DCSubtitleParser; + mem_ptr<h__DCSubtitleParser> m_Parser; + ASDCP_NO_COPY_CONSTRUCT(DCSubtitleParser); + + public: + DCSubtitleParser(); + virtual ~DCSubtitleParser(); + + // Opens the XML file for reading, parses enough data to provide a complete + // set of stream metadata for the MXFWriter below. + Result_t OpenRead(const char* filename) const; + + // Fill a TimedTextDescriptor struct with the values from the file's contents. + // Returns RESULT_INIT if the file is not open. + Result_t FillDescriptor(TimedTextDescriptor&) const; + + // Reset the contents of the internal TimedTextDescriptor + Result_t Reset() const; + + // Reads the next subtitle resource in the list taken from the XML file. + // Fails if the buffer is too small or the file list has been exhausted. + // The XML file itself is returned in the first call. + Result_t ReadFrame(FrameBuffer&) const; + }; + + + // + class MXFWriter + { + class h__Writer; + mem_ptr<h__Writer> m_Writer; + ASDCP_NO_COPY_CONSTRUCT(MXFWriter); + + public: + MXFWriter(); + virtual ~MXFWriter(); + + // Open the file for writing. The file must not exist. Returns error if + // the operation cannot be completed or if nonsensical data is discovered + // in the essence descriptor. + Result_t OpenWrite(const char* filename, const WriterInfo&, + const TimedTextDescriptor&, ui32_t HeaderSize = 16384); + + // Writes a timed-text resource to the MXF file. If the optional AESEncContext + // argument is present, the essence is encrypted prior to writing. + // Fails if the file is not open, is finalized, or an operating system + // error occurs. + Result_t WriteFrame(const FrameBuffer&, AESEncContext* = 0, HMACContext* = 0); + + // Closes the MXF file, writing the index and revised header. + Result_t Finalize(); + }; + + // + class MXFReader + { + class h__Reader; + mem_ptr<h__Reader> m_Reader; + ASDCP_NO_COPY_CONSTRUCT(MXFReader); + + public: + MXFReader(); + virtual ~MXFReader(); + + // Open the file for reading. The file must exist. Returns error if the + // operation cannot be completed. + Result_t OpenRead(const char* filename) const; + + // Returns RESULT_INIT if the file is not open. + Result_t Close() const; + + // Fill a TimedTextDescriptor struct with the values from the file's header. + // Returns RESULT_INIT if the file is not open. + Result_t FillDescriptor(TimedTextDescriptor&) const; + + // Fill a WriterInfo struct with the values from the file's header. + // Returns RESULT_INIT if the file is not open. + Result_t FillWriterInfo(WriterInfo&) const; + + // Reads a timed-text resource from the MXF file. If the optional AESEncContext + // argument is present, the resource is decrypted after reading. If the MXF + // file is encrypted and the AESDecContext argument is NULL, the frame buffer + // will contain the ciphertext frame data. If the HMACContext argument is + // not NULL, the HMAC will be calculated (if the file supports it). + // Returns RESULT_INIT if the file is not open, failure if the frame number is + // out of range, or if optional decrypt or HAMC operations fail. + Result_t ReadFrame(ui32_t frame_number, FrameBuffer&, AESDecContext* = 0, HMACContext* = 0) const; + + // Print debugging information to stream + void DumpHeaderMetadata(FILE* = 0) const; + void DumpIndex(FILE* = 0) const; + }; + } // namespace TimedText + + + +} // namespace ASDCP + + +#endif // _AS_DCP_SUBTITLE_H_ + + +// +// end AS_DCP_Subtitle.h +// diff --git a/src/AS_DCP_TimedText.cpp b/src/AS_DCP_TimedText.cpp new file mode 100644 index 0000000..ccb7c3e --- /dev/null +++ b/src/AS_DCP_TimedText.cpp @@ -0,0 +1,241 @@ +/* +Copyright (c) 2007, John Hurst +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/*! \file AS_DCP_TimedText.cpp + \version $Id$ + \brief AS-DCP library, PCM essence reader and writer implementation +*/ + + +#include "AS_DCP_internal.h" +#include "AS_DCP_TimedText.h" +#include "KM_xml.h" + +using namespace Kumu; +using namespace ASDCP; + + +//------------------------------------------------------------------------------------------ + +// +void +ASDCP::TimedText::FrameBuffer::Dump(FILE* stream, ui32_t dump_len) const +{ + if ( stream == 0 ) + stream = stderr; + + UUID TmpID(m_AssetID); + char buf[64]; + fprintf(stream, "ID: %s (type %s)\n", TmpID.EncodeHex(buf, 64), m_MIMEType.c_str()); + + if ( dump_len > 0 ) + Kumu::hexdump(m_Data, dump_len, stream); +} + +//------------------------------------------------------------------------------------------ + +class ASDCP::TimedText::MXFReader::h__Reader : public ASDCP::h__Reader +{ + TimedTextDescriptor* m_EssenceDescriptor; + + ASDCP_NO_COPY_CONSTRUCT(h__Reader); + +public: + TimedTextDescriptor m_TDesc; + + h__Reader() : m_EssenceDescriptor(0) {} + Result_t OpenRead(const char*); + Result_t ReadFrame(ui32_t, FrameBuffer&, AESDecContext*, HMACContext*); + Result_t ReadFrameGOPStart(ui32_t, FrameBuffer&, AESDecContext*, HMACContext*); + Result_t MD_to_TimedText_PDesc(TimedText::TimedTextDescriptor& TDesc); +}; + +//------------------------------------------------------------------------------------------ + +ASDCP::TimedText::MXFReader::MXFReader() +{ + m_Reader = new h__Reader; +} + + +ASDCP::TimedText::MXFReader::~MXFReader() +{ +} + +// Open the file for reading. The file must exist. Returns error if the +// operation cannot be completed. +ASDCP::Result_t +ASDCP::TimedText::MXFReader::OpenRead(const char* filename) const +{ + return m_Reader->OpenRead(filename); +} + +// +ASDCP::Result_t +ASDCP::TimedText::MXFReader::ReadFrame(ui32_t FrameNum, FrameBuffer& FrameBuf, + AESDecContext* Ctx, HMACContext* HMAC) const +{ + if ( m_Reader && m_Reader->m_File.IsOpen() ) + return m_Reader->ReadFrame(FrameNum, FrameBuf, Ctx, HMAC); + + return RESULT_INIT; +} + + +// Fill the struct with the values from the file's header. +// Returns RESULT_INIT if the file is not open. +ASDCP::Result_t +ASDCP::TimedText::MXFReader::FillDescriptor(TimedText::TimedTextDescriptor& TDesc) const +{ + if ( m_Reader && m_Reader->m_File.IsOpen() ) + { + TDesc = m_Reader->m_TDesc; + return RESULT_OK; + } + + return RESULT_INIT; +} + + +// Fill the struct with the values from the file's header. +// Returns RESULT_INIT if the file is not open. +ASDCP::Result_t +ASDCP::TimedText::MXFReader::FillWriterInfo(WriterInfo& Info) const +{ + if ( m_Reader && m_Reader->m_File.IsOpen() ) + { + Info = m_Reader->m_Info; + return RESULT_OK; + } + + return RESULT_INIT; +} + +// +void +ASDCP::TimedText::MXFReader::DumpHeaderMetadata(FILE* stream) const +{ + if ( m_Reader->m_File.IsOpen() ) + m_Reader->m_HeaderPart.Dump(stream); +} + + +// +void +ASDCP::TimedText::MXFReader::DumpIndex(FILE* stream) const +{ + if ( m_Reader->m_File.IsOpen() ) + m_Reader->m_FooterPart.Dump(stream); +} + +//------------------------------------------------------------------------------------------ + + +// +class ASDCP::TimedText::MXFWriter::h__Writer : public ASDCP::h__Writer +{ +public: + TimedTextDescriptor m_TDesc; + byte_t m_EssenceUL[SMPTE_UL_LENGTH]; + + ASDCP_NO_COPY_CONSTRUCT(h__Writer); + + h__Writer() { + memset(m_EssenceUL, 0, SMPTE_UL_LENGTH); + } + + ~h__Writer(){} + + Result_t OpenWrite(const char*, ui32_t HeaderSize); + Result_t SetSourceStream(const TimedTextDescriptor&); + Result_t WriteFrame(const FrameBuffer&, AESEncContext* = 0, HMACContext* = 0); + Result_t Finalize(); + Result_t TimedText_PDesc_to_MD(TimedText::TimedTextDescriptor& PDesc); +}; + + +//------------------------------------------------------------------------------------------ + +ASDCP::TimedText::MXFWriter::MXFWriter() +{ +} + +ASDCP::TimedText::MXFWriter::~MXFWriter() +{ +} + + +// Open the file for writing. The file must not exist. Returns error if +// the operation cannot be completed. +ASDCP::Result_t +ASDCP::TimedText::MXFWriter::OpenWrite(const char* filename, const WriterInfo& Info, + const TimedTextDescriptor& TDesc, ui32_t HeaderSize) +{ + m_Writer = new h__Writer; + + Result_t result = m_Writer->OpenWrite(filename, HeaderSize); + + if ( ASDCP_SUCCESS(result) ) + { + m_Writer->m_Info = Info; + result = m_Writer->SetSourceStream(TDesc); + } + + if ( ASDCP_FAILURE(result) ) + m_Writer.release(); + + return result; +} + + +// Writes a frame of essence to the MXF file. If the optional AESEncContext +// argument is present, the essence is encrypted prior to writing. +// Fails if the file is not open, is finalized, or an operating system +// error occurs. +ASDCP::Result_t +ASDCP::TimedText::MXFWriter::WriteFrame(const FrameBuffer& FrameBuf, AESEncContext* Ctx, HMACContext* HMAC) +{ + if ( m_Writer.empty() ) + return RESULT_INIT; + + return m_Writer->WriteFrame(FrameBuf, Ctx, HMAC); +} + +// Closes the MXF file, writing the index and other closing information. +ASDCP::Result_t +ASDCP::TimedText::MXFWriter::Finalize() +{ + if ( m_Writer.empty() ) + return RESULT_INIT; + + return m_Writer->Finalize(); +} + + + +// +// end AS_DCP_timedText.cpp +// diff --git a/src/TimedText_Parser.cpp b/src/TimedText_Parser.cpp new file mode 100644 index 0000000..86236d5 --- /dev/null +++ b/src/TimedText_Parser.cpp @@ -0,0 +1,131 @@ +/* +Copyright (c) 2007, John Hurst +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/*! \file AS_DCP_TimedText.cpp + \version $Id$ + \brief AS-DCP library, PCM essence reader and writer implementation +*/ + + +#include "AS_DCP_internal.h" +#include "AS_DCP_TimedText.h" +#include "KM_xml.h" + +using namespace Kumu; +using namespace ASDCP; + +//------------------------------------------------------------------------------------------ + +class ASDCP::TimedText::DCSubtitleParser::h__DCSubtitleParser +{ + ui32_t m_FileReadCount; + + ASDCP_NO_COPY_CONSTRUCT(h__DCSubtitleParser); + +public: + TimedTextDescriptor m_TDesc; + + h__DCSubtitleParser() : m_FileReadCount(0) + { + memset(&m_TDesc, 0, sizeof(m_TDesc)); + } + + ~h__DCSubtitleParser() + { + Close(); + } + + Result_t OpenRead(const char* filename); + void Close() {} + + Result_t Reset() + { + m_FileReadCount = 0; + return RESULT_OK; + } + + Result_t ReadFrame(FrameBuffer&); +}; + +//------------------------------------------------------------------------------------------ + +ASDCP::TimedText::DCSubtitleParser::DCSubtitleParser() +{ +} + +ASDCP::TimedText::DCSubtitleParser::~DCSubtitleParser() +{ +} + +// Opens the stream for reading, parses enough data to provide a complete +// set of stream metadata for the MXFWriter below. +ASDCP::Result_t +ASDCP::TimedText::DCSubtitleParser::OpenRead(const char* filename) const +{ + const_cast<ASDCP::TimedText::DCSubtitleParser*>(this)->m_Parser = new h__DCSubtitleParser; + + Result_t result = m_Parser->OpenRead(filename); + + if ( ASDCP_FAILURE(result) ) + const_cast<ASDCP::TimedText::DCSubtitleParser*>(this)->m_Parser.release(); + + return result; +} + +// Rewinds the stream to the beginning. +ASDCP::Result_t +ASDCP::TimedText::DCSubtitleParser::Reset() const +{ + if ( m_Parser.empty() ) + return RESULT_INIT; + + return m_Parser->Reset(); +} + +// Places a frame of data in the frame buffer. Fails if the buffer is too small +// or the stream is empty. +ASDCP::Result_t +ASDCP::TimedText::DCSubtitleParser::ReadFrame(FrameBuffer& FB) const +{ + if ( m_Parser.empty() ) + return RESULT_INIT; + + return m_Parser->ReadFrame(FB); +} + +ASDCP::Result_t +ASDCP::TimedText::DCSubtitleParser::FillDescriptor(TimedTextDescriptor& PDesc) const +{ + if ( m_Parser.empty() ) + return RESULT_INIT; + + PDesc = m_Parser->m_TDesc; + return RESULT_OK; +} + +// +// end AS_DCP_timedText.cpp +// |
