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