1 /*****************************************************************
2 |
3 |    AP4 - File Processor
4 |
5 |    Copyright 2002-2015 Axiomatic Systems, LLC
6 |
7 |
8 |    This file is part of Bento4/AP4 (MP4 Atom Processing Library).
9 |
10 |    Unless you have obtained Bento4 under a difference license,
11 |    this version of Bento4 is Bento4|GPL.
12 |    Bento4|GPL is free software; you can redistribute it and/or modify
13 |    it under the terms of the GNU General Public License as published by
14 |    the Free Software Foundation; either version 2, or (at your option)
15 |    any later version.
16 |
17 |    Bento4|GPL is distributed in the hope that it will be useful,
18 |    but WITHOUT ANY WARRANTY; without even the implied warranty of
19 |    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20 |    GNU General Public License for more details.
21 |
22 |    You should have received a copy of the GNU General Public License
23 |    along with Bento4|GPL; see the file COPYING.  If not, write to the
24 |    Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
25 |    02111-1307, USA.
26 |
27 ****************************************************************/
28 
29 #ifndef _AP4_PROCESSOR_H_
30 #define _AP4_PROCESSOR_H_
31 
32 /*----------------------------------------------------------------------
33 |   includes
34 +---------------------------------------------------------------------*/
35 #include "Ap4Types.h"
36 #include "Ap4AtomFactory.h"
37 #include "Ap4File.h"
38 #include "Ap4Track.h"
39 #include "Ap4Sample.h"
40 
41 /*----------------------------------------------------------------------
42 |   class references
43 +---------------------------------------------------------------------*/
44 class AP4_ContainerAtom;
45 class AP4_ByteStream;
46 class AP4_DataBuffer;
47 class AP4_TrakAtom;
48 class AP4_TrexAtom;
49 class AP4_SidxAtom;
50 class AP4_FragmentSampleTable;
51 struct AP4_AtomLocator;
52 
53 /*----------------------------------------------------------------------
54 |   AP4_Processor
55 +---------------------------------------------------------------------*/
56 class AP4_Processor {
57 public:
58     /**
59      * Abstract class that defines the interface implemented by progress
60      * listeners. A progress listener is called during the AP4_Processor::Process()
61      * method to notify of progres information.
62      */
63     class ProgressListener {
64     public:
~ProgressListener()65         virtual ~ProgressListener() {}
66 
67         /**
68          * This method is called during the call to AP4_Processor::Process() to
69          * notify of the progress of the operation. If this method returns an
70          * error result, processing is aborted.
71          * @param step Ordinal of the current progress step.
72          * @param total Total number of steps.
73          * @return A result code. If this method returns AP4_SUCCESS, the
74          * processing continues. If an error code is returned, the processing
75          * is aborted.
76          */
77         virtual AP4_Result OnProgress(unsigned int step,
78                                       unsigned int total) = 0;
79     };
80 
81     /**
82      * Abstract class that defines the interface implemented by concrete
83      * track handlers. A track handler is responsible for processing a
84      * track and its media samples.
85      */
86     class TrackHandler {
87     public:
AP4_IMPLEMENT_DYNAMIC_CAST(TrackHandler)88         AP4_IMPLEMENT_DYNAMIC_CAST(TrackHandler)
89 
90         /**
91          * Default destructor.
92          */
93         virtual ~TrackHandler() {}
94 
95         /**
96          * A track handler may override this method if it needs to modify
97          * the track atoms before processing the track samples.
98          */
ProcessTrack()99         virtual AP4_Result ProcessTrack() { return AP4_SUCCESS; }
100 
101         /**
102          * Returns the size of a sample after processing.
103          * @param sample Sample of which the processed size is requested.
104          * @return Size of the sample data after processing.
105          */
GetProcessedSampleSize(AP4_Sample & sample)106         virtual AP4_Size GetProcessedSampleSize(AP4_Sample& sample) { return sample.GetSize(); }
107 
108         /**
109          * Process the data of one sample.
110          * @param data_in Data buffer with the data of the sample to process.
111          * @param data_out Data buffer in which the processed sample data is
112          * returned.
113          */
114         virtual AP4_Result ProcessSample(AP4_DataBuffer& data_in,
115                                          AP4_DataBuffer& data_out) = 0;
116     };
117 
118     /**
119      * Abstract class that defines the interface implemented by concrete
120      * fragment handlers. A fragment handler is responsible for processing a
121      * fragment and its media samples.
122      */
123     class FragmentHandler {
124     public:
125         /**
126          * Default destructor.
127          */
~FragmentHandler()128         virtual ~FragmentHandler() {}
129 
130         /**
131          * A fragment handler may override this method if it needs to modify
132          * the fragment atoms before processing the fragment samples.
133          */
ProcessFragment()134         virtual AP4_Result ProcessFragment() { return AP4_SUCCESS; }
135 
136         /**
137          * A fragment handler may override this method if it needs to inspect
138          * the samples before they are written out.
139          */
PrepareForSamples(AP4_FragmentSampleTable *)140         virtual AP4_Result PrepareForSamples(AP4_FragmentSampleTable* /* sample_table */) {
141             return AP4_SUCCESS;
142         }
143 
144         /**
145          * A fragment handler may override this method if it needs to modify
146          * the fragment atoms after processing the fragment samples.
147          * NOTE: this method MUST NOT change the size of any of the atoms.
148          */
FinishFragment()149         virtual AP4_Result FinishFragment() { return AP4_SUCCESS; }
150 
151         /**
152          * Process the data of one sample.
153          * @param data_in Data buffer with the data of the sample to process.
154          * @param data_out Data buffer in which the processed sample data is
155          * returned.
156          */
157         virtual AP4_Result ProcessSample(AP4_DataBuffer& data_in,
158                                          AP4_DataBuffer& data_out) = 0;
159     };
160 
161     /**
162      *  Default destructor
163      */
~AP4_Processor()164     virtual ~AP4_Processor() { m_ExternalTrackData.DeleteReferences(); }
165 
166     /**
167      * Process the input stream into an output stream.
168      * @param input Input stream from which to read the input file.
169      * @param output Output stream to which the processed input
170      * will be written.
171      * @param listener Pointer to a listener, or NULL. The listener
172      * will be called one or more times before this method returns,
173      * with progress information.
174      */
175     AP4_Result Process(AP4_ByteStream&   input,
176                        AP4_ByteStream&   output,
177                        ProgressListener* listener = NULL,
178                        AP4_AtomFactory&  atom_factory =
179                            AP4_DefaultAtomFactory::Instance_);
180 
181     /**
182      * Process a fragment input stream into an output stream.
183      * @param fragments Input stream from which to read the fragments.
184      * @param output Output stream to which the processed fragments
185      * will be written.
186      * @param init Input stream from which to read the init data.
187      * @param listener Pointer to a listener, or NULL. The listener
188      * will be called one or more times before this method returns,
189      * with progress information.
190      */
191     AP4_Result Process(AP4_ByteStream&   fragments,
192                        AP4_ByteStream&   output,
193                        AP4_ByteStream&   init,
194                        ProgressListener* listener = NULL,
195                        AP4_AtomFactory&  atom_factory =
196                            AP4_DefaultAtomFactory::Instance_);
197 
198     /**
199      * This method can be overridden by concrete subclasses.
200      * It is called just after the input stream has been parsed into
201      * an atom tree, before the processing of the tracks.
202      * @param top_level Container atom containing all the atoms parsed
203      * from the input stream. Note that this atom does not actually
204      * exist in the file; it is a synthetised container created for the
205      * purpose of holding together all the input's top-level atoms.
206      */
207     virtual AP4_Result Initialize(AP4_AtomParent&   top_level,
208                                   AP4_ByteStream&   stream,
209                                   ProgressListener* listener = NULL);
210 
211     /**
212      * This method can be overridden by concrete subclasses.
213      * It is called just after the tracks have been processed.
214      */
215     virtual AP4_Result Finalize(AP4_AtomParent&   top_level,
216                                 ProgressListener* listener = NULL);
217 
218     /**
219      * This method can be overridden by concrete subclasses.
220      * It is called once for each track in the input file.
221      * @param trak Pointer to the track for which a handler should be
222      * created.
223      * @return A pointer to a track handler, or NULL if no handler
224      * needs to be created for that track.
225      */
CreateTrackHandler(AP4_TrakAtom * trak)226     virtual TrackHandler* CreateTrackHandler(AP4_TrakAtom* trak) { (void)trak; return NULL; }
227 
228     /**
229      * This method can be overridden by concrete subclasses.
230      * It is called once for each fragment in the input file.
231      * @param trak Pointer to the 'trak' atom that matches the track for this fragment
232      * @param trex Pointer to the 'trex' atom that defines the defaults for this track fragment
233      * @param traf Pointer to the fragment for which a handler should be created.
234      * @return A pointer to a fragment handler, or NULL if no handler
235      * needs to be created for that fragment.
236      */
237     virtual FragmentHandler* CreateFragmentHandler(AP4_TrakAtom*      trak,
238                                                    AP4_TrexAtom*      trex,
239                                                    AP4_ContainerAtom* traf,
240                                                    AP4_ByteStream&    moof_data,
241                                                    AP4_Position       moof_offset);
242 
243 protected:
244     class ExternalTrackData {
245     public:
ExternalTrackData(unsigned int track_id,AP4_ByteStream * media_data)246         ExternalTrackData(unsigned int track_id, AP4_ByteStream* media_data) :
247             m_TrackId(track_id), m_MediaData(media_data) {
248             media_data->AddReference();
249         }
~ExternalTrackData()250         ~ExternalTrackData() { m_MediaData->Release(); }
251         unsigned int    m_TrackId;
252         AP4_ByteStream* m_MediaData;
253     };
254 
255     AP4_Result Process(AP4_ByteStream&   input,
256                        AP4_ByteStream&   output,
257                        AP4_ByteStream*   fragments,
258                        ProgressListener* listener,
259                        AP4_AtomFactory&  atom_factory);
260 
261     AP4_Result ProcessFragments(AP4_MoovAtom*              moov,
262                                 AP4_List<AP4_AtomLocator>& atoms,
263                                 AP4_ContainerAtom*         mfra,
264                                 AP4_SidxAtom*              sidx,
265                                 AP4_Position               sidx_position,
266                                 AP4_ByteStream&            input,
267                                 AP4_ByteStream&            output);
268 
269 
270     AP4_List<ExternalTrackData> m_ExternalTrackData;
271     AP4_Array<AP4_UI32>         m_TrackIds;
272     AP4_Array<TrackHandler*>    m_TrackHandlers;
273 };
274 
275 #endif // _AP4_PROCESSOR_H_
276