00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include "Ap4.h"
00033 #include "Ap4AtomFactory.h"
00034 #include "Ap4SampleEntry.h"
00035 #include "Ap4IsmaCryp.h"
00036 #include "Ap4UrlAtom.h"
00037 #include "Ap4MoovAtom.h"
00038 #include "Ap4MvhdAtom.h"
00039 #include "Ap4TrakAtom.h"
00040 #include "Ap4HdlrAtom.h"
00041 #include "Ap4DrefAtom.h"
00042 #include "Ap4TkhdAtom.h"
00043 #include "Ap4MdhdAtom.h"
00044 #include "Ap4StsdAtom.h"
00045 #include "Ap4StscAtom.h"
00046 #include "Ap4StcoAtom.h"
00047 #include "Ap4Co64Atom.h"
00048 #include "Ap4StszAtom.h"
00049 #include "Ap4EsdsAtom.h"
00050 #include "Ap4SttsAtom.h"
00051 #include "Ap4CttsAtom.h"
00052 #include "Ap4StssAtom.h"
00053 #include "Ap4FtypAtom.h"
00054 #include "Ap4VmhdAtom.h"
00055 #include "Ap4SmhdAtom.h"
00056 #include "Ap4NmhdAtom.h"
00057 #include "Ap4HmhdAtom.h"
00058 #include "Ap4SchmAtom.h"
00059 #include "Ap4FrmaAtom.h"
00060 #include "Ap4TimsAtom.h"
00061 #include "Ap4RtpAtom.h"
00062 #include "Ap4SdpAtom.h"
00063 #include "Ap4IkmsAtom.h"
00064 #include "Ap4IsfmAtom.h"
00065 #include "Ap4TrefTypeAtom.h"
00066 #include "Ap4AvcCAtom.h"
00067 #include "Ap4FtabAtom.h"
00068 #include "Ap4ChplAtom.h"
00069 #include "Ap4DataAtom.h"
00070
00071
00072
00073
00074 AP4_AtomFactory AP4_AtomFactory::DefaultFactory;
00075
00076
00077
00078
00079 AP4_Result
00080 AP4_AtomFactory::AddTypeHandler(TypeHandler* handler)
00081 {
00082 return m_TypeHandlers.Add(handler);
00083 }
00084
00085
00086
00087
00088 AP4_Result
00089 AP4_AtomFactory::RemoveTypeHandler(TypeHandler* handler)
00090 {
00091 return m_TypeHandlers.Remove(handler);
00092 }
00093
00094
00095
00096
00097 AP4_Result
00098 AP4_AtomFactory::CreateAtomFromStream(AP4_ByteStream& stream,
00099 AP4_Atom*& atom)
00100 {
00101 AP4_Size bytes_available = 0;
00102 if (AP4_FAILED(stream.GetSize(bytes_available)) ||
00103 bytes_available == 0) {
00104 bytes_available = (AP4_Size)((unsigned long)(-1));
00105 }
00106 return CreateAtomFromStream(stream, bytes_available, atom);
00107 }
00108
00109
00110
00111
00112 AP4_Result
00113 AP4_AtomFactory::CreateAtomFromStream(AP4_ByteStream& stream,
00114 AP4_Size& bytes_available,
00115 AP4_Atom*& atom)
00116 {
00117 AP4_Result result;
00118
00119
00120 atom = NULL;
00121
00122
00123 if (bytes_available < 8) return AP4_ERROR_EOS;
00124
00125
00126 AP4_Offset start;
00127 stream.Tell(start);
00128
00129
00130 AP4_UI32 size;
00131 result = stream.ReadUI32(size);
00132 if (AP4_FAILED(result)) {
00133 stream.Seek(start);
00134 return result;
00135 }
00136
00137 if (size == 0) {
00138
00139 AP4_Size streamSize = 0;
00140 stream.GetSize(streamSize);
00141 if (streamSize >= start) {
00142 size = streamSize - start;
00143 }
00144 }
00145
00146
00147 if (size != 1 && size < 8 || size > bytes_available) {
00148 stream.Seek(start);
00149 return AP4_ERROR_INVALID_FORMAT;
00150 }
00151
00152
00153 AP4_Atom::Type type;
00154 result = stream.ReadUI32(type);
00155 if (AP4_FAILED(result)) {
00156 stream.Seek(start);
00157 return result;
00158 }
00159
00160 if (size == 1)
00161 {
00162 AP4_UI32 size_high;
00163
00164 result = stream.ReadUI32(size_high);
00165 if (AP4_FAILED(result) || size_high) {
00166 stream.Seek(start);
00167 return AP4_ERROR_INVALID_FORMAT;
00168 }
00169
00170 result = stream.ReadUI32(size);
00171 if (AP4_FAILED(result)) {
00172 stream.Seek(start);
00173 return result;
00174 }
00175 }
00176
00177
00178 switch (type) {
00179 case AP4_ATOM_TYPE_MOOV:
00180 atom = new AP4_MoovAtom(size, stream, *this);
00181 break;
00182
00183 case AP4_ATOM_TYPE_MVHD:
00184 atom = new AP4_MvhdAtom(size, stream);
00185 break;
00186
00187 case AP4_ATOM_TYPE_TRAK:
00188 atom = new AP4_TrakAtom(size, stream, *this);
00189 break;
00190
00191 case AP4_ATOM_TYPE_HDLR:
00192 atom = new AP4_HdlrAtom(size, stream);
00193 break;
00194
00195 case AP4_ATOM_TYPE_DREF:
00196 atom = new AP4_DrefAtom(size, stream, *this);
00197 break;
00198
00199 case AP4_ATOM_TYPE_URL:
00200 atom = new AP4_UrlAtom(size, stream);
00201 break;
00202
00203 case AP4_ATOM_TYPE_TKHD:
00204 atom = new AP4_TkhdAtom(size, stream);
00205 break;
00206
00207 case AP4_ATOM_TYPE_MDHD:
00208 atom = new AP4_MdhdAtom(size, stream);
00209 break;
00210
00211 case AP4_ATOM_TYPE_STSD:
00212 atom = new AP4_StsdAtom(size, stream, *this);
00213 break;
00214
00215 case AP4_ATOM_TYPE_STSC:
00216 atom = new AP4_StscAtom(size, stream);
00217 break;
00218
00219 case AP4_ATOM_TYPE_STCO:
00220 atom = new AP4_StcoAtom(size, stream);
00221 break;
00222
00223 case AP4_ATOM_TYPE_CO64:
00224 atom = new AP4_Co64Atom(size, stream);
00225 break;
00226
00227 case AP4_ATOM_TYPE_STSZ:
00228 atom = new AP4_StszAtom(size, stream);
00229 break;
00230
00231 case AP4_ATOM_TYPE_STTS:
00232 atom = new AP4_SttsAtom(size, stream);
00233 break;
00234
00235 case AP4_ATOM_TYPE_CTTS:
00236 atom = new AP4_CttsAtom(size, stream);
00237 break;
00238
00239 case AP4_ATOM_TYPE_STSS:
00240 atom = new AP4_StssAtom(size, stream);
00241 break;
00242
00243 case AP4_ATOM_TYPE_MP4S:
00244 atom = new AP4_Mp4sSampleEntry(size, stream, *this);
00245 break;
00246
00247 case AP4_ATOM_TYPE_MP4A:
00248 atom = new AP4_Mp4aSampleEntry(size, stream, *this);
00249 break;
00250
00251 case AP4_ATOM_TYPE_MP4V:
00252 atom = new AP4_Mp4vSampleEntry(size, stream, *this);
00253 break;
00254
00255 case AP4_ATOM_TYPE_AVC1:
00256 atom = new AP4_Avc1SampleEntry(size, stream, *this);
00257 break;
00258
00259 case AP4_ATOM_TYPE_ENCA:
00260 atom = new AP4_EncaSampleEntry(size, stream, *this);
00261 break;
00262
00263 case AP4_ATOM_TYPE_ENCV:
00264 atom = new AP4_EncvSampleEntry(size, stream, *this);
00265 break;
00266
00267 case AP4_ATOM_TYPE_ESDS:
00268 atom = new AP4_EsdsAtom(size, stream);
00269 break;
00270
00271 case AP4_ATOM_TYPE_VMHD:
00272 atom = new AP4_VmhdAtom(size, stream);
00273 break;
00274
00275 case AP4_ATOM_TYPE_SMHD:
00276 atom = new AP4_SmhdAtom(size, stream);
00277 break;
00278
00279 case AP4_ATOM_TYPE_NMHD:
00280 atom = new AP4_NmhdAtom(size, stream);
00281 break;
00282
00283 case AP4_ATOM_TYPE_HMHD:
00284 atom = new AP4_HmhdAtom(size, stream);
00285 break;
00286
00287 case AP4_ATOM_TYPE_FRMA:
00288 atom = new AP4_FrmaAtom(size, stream);
00289 break;
00290
00291 case AP4_ATOM_TYPE_SCHM:
00292 atom = new AP4_SchmAtom(size, stream);
00293 break;
00294
00295 case AP4_ATOM_TYPE_FTYP:
00296 atom = new AP4_FtypAtom(size, stream);
00297 break;
00298
00299 case AP4_ATOM_TYPE_RTP:
00300 if (m_Context == AP4_ATOM_TYPE_HNTI) {
00301 atom = new AP4_RtpAtom(size, stream);
00302 } else {
00303 atom = new AP4_RtpHintSampleEntry(size, stream, *this);
00304 }
00305 break;
00306
00307 case AP4_ATOM_TYPE_TIMS:
00308 atom = new AP4_TimsAtom(size, stream);
00309 break;
00310
00311 case AP4_ATOM_TYPE_SDP:
00312 atom = new AP4_SdpAtom(size, stream);
00313 break;
00314
00315 case AP4_ATOM_TYPE_IKMS:
00316 atom = new AP4_IkmsAtom(size, stream);
00317 break;
00318
00319 case AP4_ATOM_TYPE_ISFM:
00320 atom = new AP4_IsfmAtom(size, stream);
00321 break;
00322
00323 case AP4_ATOM_TYPE_HINT:
00324 atom = new AP4_TrefTypeAtom(type, size, stream);
00325 break;
00326
00327
00328 case AP4_ATOM_TYPE_TREF:
00329 case AP4_ATOM_TYPE_HNTI:
00330 case AP4_ATOM_TYPE_STBL:
00331 case AP4_ATOM_TYPE_MDIA:
00332 case AP4_ATOM_TYPE_DINF:
00333 case AP4_ATOM_TYPE_MINF:
00334 case AP4_ATOM_TYPE_SCHI:
00335 case AP4_ATOM_TYPE_SINF:
00336 case AP4_ATOM_TYPE_UDTA:
00337 case AP4_ATOM_TYPE_ILST:
00338 case AP4_ATOM_TYPE_NAM:
00339 case AP4_ATOM_TYPE_ART:
00340 case AP4_ATOM_TYPE_WRT:
00341 case AP4_ATOM_TYPE_ALB:
00342 case AP4_ATOM_TYPE_DAY:
00343 case AP4_ATOM_TYPE_TOO:
00344 case AP4_ATOM_TYPE_CMT:
00345 case AP4_ATOM_TYPE_GEN:
00346 case AP4_ATOM_TYPE_TRKN:
00347 case AP4_ATOM_TYPE_EDTS: {
00348 AP4_UI32 context = m_Context;
00349 m_Context = type;
00350 atom = new AP4_ContainerAtom(type, size, false, stream, *this);
00351 m_Context = context;
00352 break;
00353 }
00354
00355
00356 case AP4_ATOM_TYPE_META:
00357 atom = new AP4_ContainerAtom(type, size, true, stream, *this);
00358 break;
00359
00360
00361
00362 case AP4_ATOM_TYPE_AVCC:
00363 atom = new AP4_AvcCAtom(size, stream);
00364 break;
00365
00366 case AP4_ATOM_TYPE_TEXT:
00367 atom = new AP4_TextSampleEntry(size, stream, *this);
00368 break;
00369
00370 case AP4_ATOM_TYPE_TX3G:
00371 atom = new AP4_Tx3gSampleEntry(size, stream, *this);
00372 break;
00373
00374 case AP4_ATOM_TYPE_FTAB:
00375 atom = new AP4_FtabAtom(size, stream);
00376 break;
00377
00378 case AP4_ATOM_TYPE_S263:
00379 atom = new AP4_VisualSampleEntry(AP4_ATOM_TYPE_S263, size, stream, *this);
00380 break;
00381
00382 case AP4_ATOM_TYPE_SAMR:
00383 atom = new AP4_AudioSampleEntry(AP4_ATOM_TYPE_SAMR, size, stream, *this);
00384 break;
00385
00386 case AP4_ATOM_TYPE_CHPL:
00387 atom = new AP4_ChplAtom(size, stream);
00388 break;
00389
00390 case AP4_ATOM_TYPE_DATA:
00391 atom = new AP4_DataAtom(size, stream);
00392 break;
00393
00394 default:
00395
00396 {
00397 atom = NULL;
00398 AP4_List<TypeHandler>::Item* handler_item = m_TypeHandlers.FirstItem();
00399 while (handler_item) {
00400 TypeHandler* handler = handler_item->GetData();
00401 if (AP4_SUCCEEDED(handler->CreateAtom(type, size, stream, atom))) {
00402 break;
00403 }
00404 handler_item = handler_item->GetNext();
00405 }
00406 if (atom == NULL) {
00407
00408 atom = new AP4_UnknownAtom(type, size, false, stream);
00409 }
00410 break;
00411 }
00412 }
00413
00414
00415 bytes_available -= size;
00416 result = stream.Seek(start+size);
00417 if (AP4_FAILED(result)) {
00418 delete atom;
00419 atom = NULL;
00420 }
00421
00422 return result;
00423 }
00424