2 Copyright (c) 2013-2013, John Hurst
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions
8 1. Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
10 2. Redistributions in binary form must reproduce the above copyright
11 notice, this list of conditions and the following disclaimer in the
12 documentation and/or other materials provided with the distribution.
13 3. The name of the author may not be used to endorse or promote products
14 derived from this software without specific prior written permission.
16 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 /*! \file AtmosSyncChannel_Mixer.h
29 \brief AS-DCP library, DCinema data seqence reader implementation
38 #include "KM_fileio.h"
41 using ASDCP::Result_t;
43 //------------------------------------------------------------------------------------------
53 class ASDCP::DCData::FileList : public std::list<std::string>
55 std::string m_DirName;
61 const FileList& operator=(const std::list<std::string>& pathlist) {
62 std::list<std::string>::const_iterator i;
63 for ( i = pathlist.begin(); i != pathlist.end(); i++ )
69 Result_t InitFromDirectory(const std::string& path)
71 char next_file[Kumu::MaxFilePath];
72 Kumu::DirScanner Scanner;
74 Result_t result = Scanner.Open(path);
76 if ( ASDCP_SUCCESS(result) )
80 while ( ASDCP_SUCCESS(Scanner.GetNext(next_file)) )
82 if ( next_file[0] == '.' ) // no hidden files or internal links
85 std::string Str(m_DirName);
89 if ( ! Kumu::PathIsDirectory(Str) )
100 //------------------------------------------------------------------------------------------
102 class ASDCP::DCData::SequenceParser::h__SequenceParser
105 Rational m_PictureRate;
107 FileList::iterator m_CurrentFile;
108 BytestreamParser m_Parser;
112 ASDCP_NO_COPY_CONSTRUCT(h__SequenceParser);
115 DCDataDescriptor m_DDesc;
117 h__SequenceParser() : m_FramesRead(0)
119 memset(&m_DDesc, 0, sizeof(m_DDesc));
120 m_DDesc.EditRate = Rational(24,1);
128 Result_t OpenRead(const std::string& filename);
129 Result_t OpenRead(const std::list<std::string>& file_list);
135 m_CurrentFile = m_FileList.begin();
139 Result_t ReadFrame(FrameBuffer&);
145 ASDCP::DCData::SequenceParser::h__SequenceParser::OpenRead()
147 if ( m_FileList.empty() )
148 return RESULT_ENDOFFILE;
150 m_CurrentFile = m_FileList.begin();
151 BytestreamParser Parser;
152 FrameBuffer TmpBuffer;
154 Kumu::fsize_t file_size = Kumu::FileSize((*m_CurrentFile).c_str());
156 if ( file_size == 0 )
157 return RESULT_NOT_FOUND;
159 assert(file_size <= 0xFFFFFFFFL);
160 Result_t result = TmpBuffer.Capacity((ui32_t) file_size);
162 if ( ASDCP_SUCCESS(result) )
163 result = Parser.OpenReadFrame((*m_CurrentFile).c_str(), TmpBuffer);
165 if ( ASDCP_SUCCESS(result) )
166 result = Parser.FillDCDataDescriptor(m_DDesc);
169 if ( ASDCP_SUCCESS(result) )
170 m_DDesc.ContainerDuration = m_FileList.size();
177 ASDCP::DCData::SequenceParser::h__SequenceParser::OpenRead(const std::string& filename)
179 Result_t result = m_FileList.InitFromDirectory(filename);
181 if ( ASDCP_SUCCESS(result) )
190 ASDCP::DCData::SequenceParser::h__SequenceParser::OpenRead(const std::list<std::string>& file_list)
192 m_FileList = file_list;
198 ASDCP::DCData::SequenceParser::h__SequenceParser::ReadFrame(FrameBuffer& FB)
200 if ( m_CurrentFile == m_FileList.end() )
201 return RESULT_ENDOFFILE;
204 Result_t result = m_Parser.OpenReadFrame((*m_CurrentFile).c_str(), FB);
206 if ( ASDCP_SUCCESS(result) )
208 FB.FrameNumber(m_FramesRead++);
216 //------------------------------------------------------------------------------------------
218 ASDCP::DCData::SequenceParser::SequenceParser()
222 ASDCP::DCData::SequenceParser::~SequenceParser()
226 // Opens the stream for reading, parses enough data to provide a complete
227 // set of stream metadata for the MXFWriter below.
229 ASDCP::DCData::SequenceParser::OpenRead(const std::string& filename) const
231 const_cast<ASDCP::DCData::SequenceParser*>(this)->m_Parser = new h__SequenceParser;
233 Result_t result = m_Parser->OpenRead(filename);
235 if ( ASDCP_FAILURE(result) )
236 const_cast<ASDCP::DCData::SequenceParser*>(this)->m_Parser.release();
243 ASDCP::DCData::SequenceParser::OpenRead(const std::list<std::string>& file_list) const
245 const_cast<ASDCP::DCData::SequenceParser*>(this)->m_Parser = new h__SequenceParser;
247 Result_t result = m_Parser->OpenRead(file_list);
249 if ( ASDCP_FAILURE(result) )
250 const_cast<ASDCP::DCData::SequenceParser*>(this)->m_Parser.release();
256 // Rewinds the stream to the beginning.
258 ASDCP::DCData::SequenceParser::Reset() const
260 if ( m_Parser.empty() )
263 return m_Parser->Reset();
266 // Places a frame of data in the frame buffer. Fails if the buffer is too small
267 // or the stream is empty.
269 ASDCP::DCData::SequenceParser::ReadFrame(FrameBuffer& FB) const
271 if ( m_Parser.empty() )
274 return m_Parser->ReadFrame(FB);
279 ASDCP::DCData::SequenceParser::FillDCDataDescriptor(DCDataDescriptor& DDesc) const
281 if ( m_Parser.empty() )
284 DDesc = m_Parser->m_DDesc;
290 // end DCData_Sequence_Parser.cpp