📄 mp4atom.cpp
字号:
/* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is MPEG4IP. * * The Initial Developer of the Original Code is Cisco Systems Inc. * Portions created by Cisco Systems Inc. are * Copyright (C) Cisco Systems Inc. 2001. All Rights Reserved. * * Contributor(s): * Dave Mackie dmackie@cisco.com */#include "mp4common.h"#include "atoms.h"MP4AtomInfo::MP4AtomInfo(const char* name, bool mandatory, bool onlyOne) { m_name = name; m_mandatory = mandatory; m_onlyOne = onlyOne; m_count = 0;}MP4Atom::MP4Atom(const char* type) { SetType(type); m_unknownType = FALSE; m_pFile = NULL; m_start = 0; m_end = 0; m_size = 0; m_pParentAtom = NULL; m_depth = 0xFF;}MP4Atom::~MP4Atom(){ u_int32_t i; for (i = 0; i < m_pProperties.Size(); i++) { delete m_pProperties[i]; } for (i = 0; i < m_pChildAtomInfos.Size(); i++) { delete m_pChildAtomInfos[i]; } for (i = 0; i < m_pChildAtoms.Size(); i++) { delete m_pChildAtoms[i]; }}MP4Atom* MP4Atom::CreateAtom(const char* type){ MP4Atom* pAtom = NULL; if (type == NULL) { pAtom = new MP4RootAtom(); } else if (type[0] == 'c') { if (ATOMID(type) == ATOMID("ctts")) { pAtom = new MP4CttsAtom(); } else if (ATOMID(type) == ATOMID("co64")) { pAtom = new MP4Co64Atom(); } else if (ATOMID(type) == ATOMID("cprt")) { pAtom = new MP4CprtAtom(); } } else if (type[0] == 'd') { if (ATOMID(type) == ATOMID("dinf")) { pAtom = new MP4DinfAtom(); } else if (ATOMID(type) == ATOMID("dref")) { pAtom = new MP4DrefAtom(); } else if (ATOMID(type) == ATOMID("dpnd")) { pAtom = new MP4TrefTypeAtom(type); } else if (ATOMID(type) == ATOMID("dmed")) { pAtom = new MP4DmedAtom(); } else if (ATOMID(type) == ATOMID("dimm")) { pAtom = new MP4DimmAtom(); } else if (ATOMID(type) == ATOMID("drep")) { pAtom = new MP4DrepAtom(); } else if (ATOMID(type) == ATOMID("dmax")) { pAtom = new MP4DmaxAtom(); } } else if (type[0] == 'e') { if (ATOMID(type) == ATOMID("esds")) { pAtom = new MP4EsdsAtom(); } else if (ATOMID(type) == ATOMID("edts")) { pAtom = new MP4EdtsAtom(); } else if (ATOMID(type) == ATOMID("elst")) { pAtom = new MP4ElstAtom(); } } else if (type[0] == 'h') { if (ATOMID(type) == ATOMID("hdlr")) { pAtom = new MP4HdlrAtom(); } else if (ATOMID(type) == ATOMID("hmhd")) { pAtom = new MP4HmhdAtom(); } else if (ATOMID(type) == ATOMID("hint")) { pAtom = new MP4TrefTypeAtom(type); } else if (ATOMID(type) == ATOMID("hnti")) { pAtom = new MP4HntiAtom(); } else if (ATOMID(type) == ATOMID("hinf")) { pAtom = new MP4HinfAtom(); } } else if (type[0] == 'm') { if (ATOMID(type) == ATOMID("mdia")) { pAtom = new MP4MdiaAtom(); } else if (ATOMID(type) == ATOMID("minf")) { pAtom = new MP4MinfAtom(); } else if (ATOMID(type) == ATOMID("mdhd")) { pAtom = new MP4MdhdAtom(); } else if (ATOMID(type) == ATOMID("mdat")) { pAtom = new MP4MdatAtom(); } else if (ATOMID(type) == ATOMID("moov")) { pAtom = new MP4MoovAtom(); } else if (ATOMID(type) == ATOMID("mvhd")) { pAtom = new MP4MvhdAtom(); } else if (ATOMID(type) == ATOMID("mpod")) { pAtom = new MP4TrefTypeAtom(type); } else if (ATOMID(type) == ATOMID("mp4a")) { pAtom = new MP4Mp4aAtom(); } else if (ATOMID(type) == ATOMID("mp4s")) { pAtom = new MP4Mp4sAtom(); } else if (ATOMID(type) == ATOMID("mp4v")) { pAtom = new MP4Mp4vAtom(); } else if (ATOMID(type) == ATOMID("moof")) { pAtom = new MP4MoofAtom(); } else if (ATOMID(type) == ATOMID("mfhd")) { pAtom = new MP4MfhdAtom(); } else if (ATOMID(type) == ATOMID("mvex")) { pAtom = new MP4MvexAtom(); } else if (ATOMID(type) == ATOMID("maxr")) { pAtom = new MP4MaxrAtom(); } } else if (type[0] == 's') { if (ATOMID(type) == ATOMID("stbl")) { pAtom = new MP4StblAtom(); } else if (ATOMID(type) == ATOMID("stsd")) { pAtom = new MP4StsdAtom(); } else if (ATOMID(type) == ATOMID("stts")) { pAtom = new MP4SttsAtom(); } else if (ATOMID(type) == ATOMID("stsz")) { pAtom = new MP4StszAtom(); } else if (ATOMID(type) == ATOMID("stsc")) { pAtom = new MP4StscAtom(); } else if (ATOMID(type) == ATOMID("stco")) { pAtom = new MP4StcoAtom(); } else if (ATOMID(type) == ATOMID("stss")) { pAtom = new MP4StssAtom(); } else if (ATOMID(type) == ATOMID("stsh")) { pAtom = new MP4StshAtom(); } else if (ATOMID(type) == ATOMID("stdp")) { pAtom = new MP4StdpAtom(); } else if (ATOMID(type) == ATOMID("smhd")) { pAtom = new MP4SmhdAtom(); } else if (ATOMID(type) == ATOMID("sdp ")) { pAtom = new MP4SdpAtom(); } else if (ATOMID(type) == ATOMID("snro")) { pAtom = new MP4SnroAtom(); } else if (ATOMID(type) == ATOMID("sync")) { pAtom = new MP4TrefTypeAtom(type); } else if (ATOMID(type) == ATOMID("skip")) { pAtom = new MP4FreeAtom(); pAtom->SetType("skip"); } } else if (type[0] == 't') { if (ATOMID(type) == ATOMID("trak")) { pAtom = new MP4TrakAtom(); } else if (ATOMID(type) == ATOMID("tkhd")) { pAtom = new MP4TkhdAtom(); } else if (ATOMID(type) == ATOMID("tref")) { pAtom = new MP4TrefAtom(); } else if (ATOMID(type) == ATOMID("traf")) { pAtom = new MP4TrafAtom(); } else if (ATOMID(type) == ATOMID("tfhd")) { pAtom = new MP4TfhdAtom(); } else if (ATOMID(type) == ATOMID("trex")) { pAtom = new MP4TrexAtom(); } else if (ATOMID(type) == ATOMID("trun")) { pAtom = new MP4TrunAtom(); } else if (ATOMID(type) == ATOMID("tmin")) { pAtom = new MP4TminAtom(); } else if (ATOMID(type) == ATOMID("tmax")) { pAtom = new MP4TmaxAtom(); } else if (ATOMID(type) == ATOMID("trpy")) { pAtom = new MP4TrpyAtom(); } else if (ATOMID(type) == ATOMID("tpyl")) { pAtom = new MP4TpylAtom(); } else if (ATOMID(type) == ATOMID("tims")) { pAtom = new MP4TimsAtom(); } else if (ATOMID(type) == ATOMID("tsro")) { pAtom = new MP4TsroAtom(); } } else if (type[0] == 'u') { if (ATOMID(type) == ATOMID("udta")) { pAtom = new MP4UdtaAtom(); } else if (ATOMID(type) == ATOMID("url ")) { pAtom = new MP4UrlAtom(); } else if (ATOMID(type) == ATOMID("urn ")) { pAtom = new MP4UrnAtom(); } } else { if (ATOMID(type) == ATOMID("free")) { pAtom = new MP4FreeAtom(); } else if (ATOMID(type) == ATOMID("ftyp")) { pAtom = new MP4FtypAtom(); } else if (ATOMID(type) == ATOMID("iods")) { pAtom = new MP4IodsAtom(); } else if (ATOMID(type) == ATOMID("ipir")) { pAtom = new MP4TrefTypeAtom(type); } else if (ATOMID(type) == ATOMID("nmhd")) { pAtom = new MP4NmhdAtom(); } else if (ATOMID(type) == ATOMID("nump")) { pAtom = new MP4NumpAtom(); } else if (ATOMID(type) == ATOMID("pmax")) { pAtom = new MP4PmaxAtom(); } else if (ATOMID(type) == ATOMID("payt")) { pAtom = new MP4PaytAtom(); } else if (ATOMID(type) == ATOMID("rtp ")) { pAtom = new MP4RtpAtom(); } else if (ATOMID(type) == ATOMID("vmhd")) { pAtom = new MP4VmhdAtom(); } } if (pAtom == NULL) { pAtom = new MP4Atom(type); pAtom->SetUnknownType(true); } ASSERT(pAtom); return pAtom;}// generate a skeletal selfvoid MP4Atom::Generate(){ u_int32_t i; // for all properties for (i = 0; i < m_pProperties.Size(); i++) { // ask it to self generate m_pProperties[i]->Generate(); } // for all mandatory, single child atom types for (i = 0; i < m_pChildAtomInfos.Size(); i++) { if (m_pChildAtomInfos[i]->m_mandatory && m_pChildAtomInfos[i]->m_onlyOne) { // create the mandatory, single child atom MP4Atom* pChildAtom = CreateAtom(m_pChildAtomInfos[i]->m_name); AddChildAtom(pChildAtom); // and ask it to self generate pChildAtom->Generate(); } }}MP4Atom* MP4Atom::ReadAtom(MP4File* pFile, MP4Atom* pParentAtom){ u_int8_t hdrSize = 8; u_int8_t extendedType[16]; u_int64_t pos = pFile->GetPosition(); VERBOSE_READ(pFile->GetVerbosity(), printf("ReadAtom: pos = 0x"LLX"\n", pos)); u_int64_t dataSize = pFile->ReadUInt32(); char type[5]; pFile->ReadBytes((u_int8_t*)&type[0], 4); type[4] = '\0'; // extended size if (dataSize == 1) { dataSize = pFile->ReadUInt64(); hdrSize += 8; } // extended type if (ATOMID(type) == ATOMID("uuid")) { pFile->ReadBytes(extendedType, sizeof(extendedType)); hdrSize += sizeof(extendedType); } if (dataSize == 0) { // extends to EOF dataSize = pFile->GetSize() - pos; } dataSize -= hdrSize; VERBOSE_READ(pFile->GetVerbosity(), printf("ReadAtom: type = %s data-size = "LLU" (0x"LLX")\n", type, dataSize, dataSize)); if (pos + hdrSize + dataSize > pParentAtom->GetEnd()) { VERBOSE_READ(pFile->GetVerbosity(), printf("ReadAtom: invalid atom size, extends outside parent atom\n")); throw new MP4Error("invalid atom size", "ReadAtom"); } MP4Atom* pAtom = CreateAtom(type); pAtom->SetFile(pFile); pAtom->SetStart(pos); pAtom->SetEnd(pos + hdrSize + dataSize); pAtom->SetSize(dataSize); if (ATOMID(type) == ATOMID("uuid")) { pAtom->SetExtendedType(extendedType); } if (pAtom->IsUnknownType()) { if (!IsReasonableType(pAtom->GetType())) { VERBOSE_READ(pFile->GetVerbosity(), printf("Warning: atom type %s is suspect\n", pAtom->GetType())); } else { VERBOSE_READ(pFile->GetVerbosity(), printf("Info: atom type %s is unknown\n", pAtom->GetType())); } if (dataSize > 0) { pAtom->AddProperty( new MP4BytesProperty("data", dataSize)); } } pAtom->SetParentAtom(pParentAtom); pAtom->Read(); return pAtom;}bool MP4Atom::IsReasonableType(const char* type){ for (u_int8_t i = 0; i < 4; i++) { if (isalnum(type[i])) { continue; } if (i == 3 && type[i] == ' ') { continue; } return false; } return true;}// generic readvoid MP4Atom::Read(){ ASSERT(m_pFile); if (ATOMID(m_type) != 0 && m_size > 1000000) { VERBOSE_READ(GetVerbosity(), printf("Warning: %s atom size "LLU" is suspect\n", m_type, m_size)); } ReadProperties(); // read child atoms, if we expect there to be some if (m_pChildAtomInfos.Size() > 0) { ReadChildAtoms(); } Skip(); // to end of atom}void MP4Atom::Skip(){ if (m_pFile->GetPosition() != m_end) { VERBOSE_READ(m_pFile->GetVerbosity(), printf("Skip: "LLU" bytes\n", m_end - m_pFile->GetPosition())); } m_pFile->SetPosition(m_end);}MP4Atom* MP4Atom::FindAtom(const char* name){ if (!IsMe(name)) { return NULL; } if (!IsRootAtom()) { VERBOSE_FIND(m_pFile->GetVerbosity(), printf("FindAtom: matched %s\n", name));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -