Add call to parent constructor.
[asdcplib-cth.git] / src / DCData_Sequence_Parser.cpp
1 /*
2 Copyright (c) 2013-2013, John Hurst
3 All rights reserved.
4
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions
7 are met:
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.
15
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.
26 */
27 /*! \file    AtmosSyncChannel_Mixer.h
28     \version $Id: DCData_Sequence_Parser.cpp,v 1.2 2014/01/02 23:29:22 jhurst Exp $
29     \brief   AS-DCP library, DCinema data seqence reader implementation
30 */
31
32 #include "AS_DCP.h"
33
34 #include <algorithm>
35 #include <list>
36 #include <string>
37
38 #include "KM_fileio.h"
39 #include "KM_log.h"
40
41 using ASDCP::Result_t;
42
43 //------------------------------------------------------------------------------------------
44 namespace ASDCP
45 {
46 namespace DCData
47 {
48 class FileList;
49 } // namespace DCData
50 } // namespace ASDCP
51
52
53 class ASDCP::DCData::FileList : public std::list<std::string>
54 {
55     std::string m_DirName;
56
57   public:
58     FileList() {}
59     ~FileList() {}
60
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++ )
64             push_back(*i);
65         return *this;
66     }
67
68     //
69     Result_t InitFromDirectory(const std::string& path)
70     {
71         char next_file[Kumu::MaxFilePath];
72         Kumu::DirScanner Scanner;
73
74         Result_t result = Scanner.Open(path);
75
76         if ( ASDCP_SUCCESS(result) )
77         {
78             m_DirName = path;
79
80             while ( ASDCP_SUCCESS(Scanner.GetNext(next_file)) )
81             {
82                 if ( next_file[0] == '.' ) // no hidden files or internal links
83                     continue;
84
85                 std::string Str(m_DirName);
86                 Str += "/";
87                 Str += next_file;
88
89                 if ( ! Kumu::PathIsDirectory(Str) )
90                     push_back(Str);
91             }
92
93             sort();
94         }
95
96         return result;
97     }
98 };
99
100 //------------------------------------------------------------------------------------------
101
102 class ASDCP::DCData::SequenceParser::h__SequenceParser
103 {
104   ui32_t             m_FramesRead;
105   Rational           m_PictureRate;
106   FileList           m_FileList;
107   FileList::iterator m_CurrentFile;
108   BytestreamParser   m_Parser;
109
110   Result_t OpenRead();
111
112   ASDCP_NO_COPY_CONSTRUCT(h__SequenceParser);
113
114  public:
115   DCDataDescriptor  m_DDesc;
116
117   h__SequenceParser() : m_FramesRead(0)
118   {
119     memset(&m_DDesc, 0, sizeof(m_DDesc));
120     m_DDesc.EditRate = Rational(24,1);
121   }
122
123   ~h__SequenceParser()
124   {
125     Close();
126   }
127
128   Result_t OpenRead(const std::string& filename);
129   Result_t OpenRead(const std::list<std::string>& file_list);
130   void     Close() {}
131
132   Result_t Reset()
133   {
134     m_FramesRead = 0;
135     m_CurrentFile = m_FileList.begin();
136     return RESULT_OK;
137   }
138
139   Result_t ReadFrame(FrameBuffer&);
140 };
141
142
143 //
144 ASDCP::Result_t
145 ASDCP::DCData::SequenceParser::h__SequenceParser::OpenRead()
146 {
147   if ( m_FileList.empty() )
148     return RESULT_ENDOFFILE;
149
150   m_CurrentFile = m_FileList.begin();
151   BytestreamParser Parser;
152   FrameBuffer TmpBuffer;
153
154   Kumu::fsize_t file_size = Kumu::FileSize((*m_CurrentFile).c_str());
155
156   if ( file_size == 0 )
157     return RESULT_NOT_FOUND;
158
159   assert(file_size <= 0xFFFFFFFFL);
160   Result_t result = TmpBuffer.Capacity((ui32_t) file_size);
161
162   if ( ASDCP_SUCCESS(result) )
163     result = Parser.OpenReadFrame((*m_CurrentFile).c_str(), TmpBuffer);
164
165   if ( ASDCP_SUCCESS(result) )
166     result = Parser.FillDCDataDescriptor(m_DDesc);
167
168   // how big is it?
169   if ( ASDCP_SUCCESS(result) )
170     m_DDesc.ContainerDuration = m_FileList.size();
171
172   return result;
173 }
174
175 //
176 ASDCP::Result_t
177 ASDCP::DCData::SequenceParser::h__SequenceParser::OpenRead(const std::string& filename)
178 {
179   Result_t result = m_FileList.InitFromDirectory(filename);
180
181   if ( ASDCP_SUCCESS(result) )
182     result = OpenRead();
183
184   return result;
185 }
186
187
188 //
189 ASDCP::Result_t
190 ASDCP::DCData::SequenceParser::h__SequenceParser::OpenRead(const std::list<std::string>& file_list)
191 {
192   m_FileList = file_list;
193   return OpenRead();
194 }
195
196 //
197 ASDCP::Result_t
198 ASDCP::DCData::SequenceParser::h__SequenceParser::ReadFrame(FrameBuffer& FB)
199 {
200   if ( m_CurrentFile == m_FileList.end() )
201     return RESULT_ENDOFFILE;
202
203   // open the file
204   Result_t result = m_Parser.OpenReadFrame((*m_CurrentFile).c_str(), FB);
205
206   if ( ASDCP_SUCCESS(result) )
207   {
208       FB.FrameNumber(m_FramesRead++);
209       m_CurrentFile++;
210   }
211
212   return result;
213 }
214
215
216 //------------------------------------------------------------------------------------------
217
218 ASDCP::DCData::SequenceParser::SequenceParser()
219 {
220 }
221
222 ASDCP::DCData::SequenceParser::~SequenceParser()
223 {
224 }
225
226 // Opens the stream for reading, parses enough data to provide a complete
227 // set of stream metadata for the MXFWriter below.
228 ASDCP::Result_t
229 ASDCP::DCData::SequenceParser::OpenRead(const std::string& filename) const
230 {
231   const_cast<ASDCP::DCData::SequenceParser*>(this)->m_Parser = new h__SequenceParser;
232
233   Result_t result = m_Parser->OpenRead(filename);
234
235   if ( ASDCP_FAILURE(result) )
236     const_cast<ASDCP::DCData::SequenceParser*>(this)->m_Parser.release();
237
238   return result;
239 }
240
241 //
242 Result_t
243 ASDCP::DCData::SequenceParser::OpenRead(const std::list<std::string>& file_list) const
244 {
245   const_cast<ASDCP::DCData::SequenceParser*>(this)->m_Parser = new h__SequenceParser;
246
247   Result_t result = m_Parser->OpenRead(file_list);
248
249   if ( ASDCP_FAILURE(result) )
250     const_cast<ASDCP::DCData::SequenceParser*>(this)->m_Parser.release();
251
252   return result;
253 }
254
255
256 // Rewinds the stream to the beginning.
257 ASDCP::Result_t
258 ASDCP::DCData::SequenceParser::Reset() const
259 {
260   if ( m_Parser.empty() )
261     return RESULT_INIT;
262
263   return m_Parser->Reset();
264 }
265
266 // Places a frame of data in the frame buffer. Fails if the buffer is too small
267 // or the stream is empty.
268 ASDCP::Result_t
269 ASDCP::DCData::SequenceParser::ReadFrame(FrameBuffer& FB) const
270 {
271   if ( m_Parser.empty() )
272     return RESULT_INIT;
273
274   return m_Parser->ReadFrame(FB);
275 }
276
277 //
278 ASDCP::Result_t
279 ASDCP::DCData::SequenceParser::FillDCDataDescriptor(DCDataDescriptor& DDesc) const
280 {
281   if ( m_Parser.empty() )
282     return RESULT_INIT;
283
284   DDesc = m_Parser->m_DDesc;
285   return RESULT_OK;
286 }
287
288
289 //
290 // end DCData_Sequence_Parser.cpp
291 //
292