mp4atom.cpp

来自「6410BSP1」· C++ 代码 · 共 896 行 · 第 1/2 页

CPP
896
字号
    if (!IsRootAtom()) {        VERBOSE_FIND(m_pFile->GetVerbosity(),            printf("FindAtom: matched %s\n", name));        name = MP4NameAfterFirst(name);        // I'm the sought after atom         if (name == NULL) {            return this;        }    }    // else it's one of my children    return FindChildAtom(name);}bool MP4Atom::FindProperty(const char *name,     MP4Property** ppProperty, u_int32_t* pIndex){    if (!IsMe(name)) {        return false;    }    if (!IsRootAtom()) {        VERBOSE_FIND(m_pFile->GetVerbosity(),            printf("FindProperty: matched %s\n", name));        name = MP4NameAfterFirst(name);        // no property name given        if (name == NULL) {            return false;        }    }    return FindContainedProperty(name, ppProperty, pIndex);}bool MP4Atom::IsMe(const char* name){    if (name == NULL) {        return false;    }    // root atom always matches    if (!strcmp(m_type, "")) {        return true;    }    // check if our atom name is specified as the first component    if (!MP4NameFirstMatches(m_type, name)) {        return false;    }    return true;}MP4Atom* MP4Atom::FindChildAtom(const char* name){    u_int32_t atomIndex = 0;    // get the index if we have one, e.g. moov.trak[2].mdia...    MP4NameFirstIndex(name, &atomIndex);    // need to get to the index'th child atom of the right type    for (u_int32_t i = 0; i < m_pChildAtoms.Size(); i++) {        if (MP4NameFirstMatches(m_pChildAtoms[i]->GetType(), name)) {            if (atomIndex == 0) {                // this is the one, ask it to match                return m_pChildAtoms[i]->FindAtom(name);            }            atomIndex--;        }    }    return NULL;}bool MP4Atom::FindContainedProperty(const char *name,    MP4Property** ppProperty, u_int32_t* pIndex){    u_int32_t numProperties = m_pProperties.Size();    u_int32_t i;    // check all of our properties    for (i = 0; i < numProperties; i++) {        if (m_pProperties[i]->FindProperty(name, ppProperty, pIndex)) {            return true;        }    }    // not one of our properties,     // presumably one of our children's properties    // check child atoms...    // check if we have an index, e.g. trak[2].mdia...    u_int32_t atomIndex = 0;    MP4NameFirstIndex(name, &atomIndex);    // need to get to the index'th child atom of the right type    for (i = 0; i < m_pChildAtoms.Size(); i++) {        if (MP4NameFirstMatches(m_pChildAtoms[i]->GetType(), name)) {            if (atomIndex == 0) {                // this is the one, ask it to match                return m_pChildAtoms[i]->FindProperty(name, ppProperty, pIndex);            }            atomIndex--;        }    }    VERBOSE_FIND(m_pFile->GetVerbosity(),        printf("FindProperty: no match for %s\n", name));    return false;}void MP4Atom::ReadProperties(u_int32_t startIndex, u_int32_t count){    u_int32_t numProperties = MIN(count, m_pProperties.Size() - startIndex);    // read any properties of the atom    for (u_int32_t i = startIndex; i < startIndex + numProperties; i++) {        m_pProperties[i]->Read(m_pFile);        if (m_pFile->GetPosition() > m_end) {            VERBOSE_READ(GetVerbosity(),                 printf("ReadProperties: insufficient data for property: %s pos 0x"X64" atom end 0x"X64"\n",                    m_pProperties[i]->GetName(),                     m_pFile->GetPosition(), m_end));             printf("\n[%s]  %s", "Atom ReadProperties parameters", "Atom ReadProperties");//            throw new MP4Error("Atom ReadProperties", "Atom ReadProperties");            RaiseException(1, 0, 0, NULL);        }        if (m_pProperties[i]->GetType() == TableProperty) {            VERBOSE_READ_TABLE(GetVerbosity(),                 printf("Read: "); m_pProperties[i]->Dump(stdout, 0, true));        } else if (m_pProperties[i]->GetType() != DescriptorProperty) {            VERBOSE_READ(GetVerbosity(),                 printf("Read: "); m_pProperties[i]->Dump(stdout, 0, true));        }    }}void MP4Atom::ReadChildAtoms(){  bool this_is_udta = ATOMID(m_type) == ATOMID("udta");    VERBOSE_READ(GetVerbosity(),         printf("ReadChildAtoms: of %s\n", m_type[0] ? m_type : "root"));    for (u_int64_t position = m_pFile->GetPosition();         position < m_end;         position = m_pFile->GetPosition()) {      // make sure that we have enough to read at least 8 bytes      // size and type.      if (m_end - position < 2 * sizeof(uint32_t)) {        // if we're reading udta, it's okay to have 4 bytes of 0        if (this_is_udta &&        m_end - position == sizeof(uint32_t)) {          u_int32_t mbz = m_pFile->ReadUInt32();          if (mbz != 0) {        VERBOSE_WARNING(GetVerbosity(),                printf("Error: In udta atom, end value is not zero %x\n",                        mbz));          }          continue;        }        // otherwise, output a warning, but don't care        VERBOSE_WARNING(GetVerbosity(),                printf("Error: In %s atom, extra "D64" bytes at end of atom\n",                    m_type, (m_end - position)));        for (uint64_t ix = 0; ix < m_end - position; ix++) {          m_pFile->ReadUInt8();        }        continue;      }        MP4Atom* pChildAtom = MP4Atom::ReadAtom(m_pFile, this);        AddChildAtom(pChildAtom);        MP4AtomInfo* pChildAtomInfo = FindAtomInfo(pChildAtom->GetType());        // if child atom is of known type        // but not expected here print warning        if (pChildAtomInfo == NULL && !pChildAtom->IsUnknownType()) {            VERBOSE_READ(GetVerbosity(),                printf("Warning: In atom %s unexpected child atom %s\n",                    GetType(), pChildAtom->GetType()));        }        // if child atoms should have just one instance        // and this is more than one, print warning        if (pChildAtomInfo) {            pChildAtomInfo->m_count++;            if (pChildAtomInfo->m_onlyOne && pChildAtomInfo->m_count > 1) {                VERBOSE_READ(GetVerbosity(),                    printf("Warning: In atom %s multiple child atoms %s\n",                        GetType(), pChildAtom->GetType()));            }        }    }    // if mandatory child atom doesn't exist, print warning    u_int32_t numAtomInfo = m_pChildAtomInfos.Size();    for (u_int32_t i = 0; i < numAtomInfo; i++) {        if (m_pChildAtomInfos[i]->m_mandatory          && m_pChildAtomInfos[i]->m_count == 0) {                VERBOSE_READ(GetVerbosity(),                    printf("Warning: In atom %s missing child atom %s\n",                        GetType(), m_pChildAtomInfos[i]->m_name));        }    }    VERBOSE_READ(GetVerbosity(),         printf("ReadChildAtoms: finished %s\n", m_type));}MP4AtomInfo* MP4Atom::FindAtomInfo(const char* name){    u_int32_t numAtomInfo = m_pChildAtomInfos.Size();    for (u_int32_t i = 0; i < numAtomInfo; i++) {        if (ATOMID(m_pChildAtomInfos[i]->m_name) == ATOMID(name)) {            return m_pChildAtomInfos[i];        }    }    return NULL;}// generic writevoid MP4Atom::Write(){    ASSERT(m_pFile);    BeginWrite();    WriteProperties();    WriteChildAtoms();    FinishWrite();}void MP4Atom::Rewrite(){       ASSERT(m_pFile);              if (!m_end) {           // This atom hasn't been written yet...           return;       }              u_int64_t fPos = m_pFile->GetPosition();       m_pFile->SetPosition(GetStart());       Write();       m_pFile->SetPosition(fPos);}void MP4Atom::BeginWrite(bool use64){    m_start = m_pFile->GetPosition();    //use64 = m_pFile->Use64Bits();    if (use64) {        m_pFile->WriteUInt32(1);    } else {        m_pFile->WriteUInt32(0);    }    m_pFile->WriteBytes((u_int8_t*)&m_type[0], 4);    if (use64) {        m_pFile->WriteUInt64(0);    }    if (ATOMID(m_type) == ATOMID("uuid")) {        m_pFile->WriteBytes(m_extendedType, sizeof(m_extendedType));    }}void MP4Atom::FinishWrite(bool use64){    m_end = m_pFile->GetPosition();    m_size = (m_end - m_start);  VERBOSE_WRITE(GetVerbosity(),         printf("end: type %s "U64" "U64" size "U64"\n", m_type,                m_start, m_end,               m_size));    //use64 = m_pFile->Use64Bits();    if (use64) {        m_pFile->SetPosition(m_start + 8);        m_pFile->WriteUInt64(m_size);    } else {        ASSERT(m_size <= (u_int64_t)0xFFFFFFFF);        m_pFile->SetPosition(m_start);        m_pFile->WriteUInt32(m_size);    }    m_pFile->SetPosition(m_end);    // adjust size to just reflect data portion of atom    m_size -= (use64 ? 16 : 8);    if (ATOMID(m_type) == ATOMID("uuid")) {        m_size -= sizeof(m_extendedType);    }}void MP4Atom::WriteProperties(u_int32_t startIndex, u_int32_t count){    u_int32_t numProperties = MIN(count, m_pProperties.Size() - startIndex);    VERBOSE_WRITE(GetVerbosity(),         printf("Write: type %s\n", m_type));    for (u_int32_t i = startIndex; i < startIndex + numProperties; i++) {        m_pProperties[i]->Write(m_pFile);        if (m_pProperties[i]->GetType() == TableProperty) {            VERBOSE_WRITE_TABLE(GetVerbosity(),                 printf("Write: "); m_pProperties[i]->Dump(stdout, 0, false));        } else {            VERBOSE_WRITE(GetVerbosity(),                 printf("Write: "); m_pProperties[i]->Dump(stdout, 0, false));        }    }}void MP4Atom::WriteChildAtoms(){    u_int32_t size = m_pChildAtoms.Size();    for (u_int32_t i = 0; i < size; i++) {        m_pChildAtoms[i]->Write();    }    VERBOSE_WRITE(GetVerbosity(),         printf("Write: finished %s\n", m_type));}void MP4Atom::AddProperty(MP4Property* pProperty) {    ASSERT(pProperty);    m_pProperties.Add(pProperty);    pProperty->SetParentAtom(this);}void MP4Atom::AddVersionAndFlags(){    AddProperty(new MP4Integer8Property("version"));    AddProperty(new MP4Integer24Property("flags"));}void MP4Atom::AddReserved(char* name, u_int32_t size) {    MP4BytesProperty* pReserved = new MP4BytesProperty(name, size);     pReserved->SetReadOnly();    AddProperty(pReserved);}void MP4Atom::ExpectChildAtom(const char* name, bool mandatory, bool onlyOne){    m_pChildAtomInfos.Add(new MP4AtomInfo(name, mandatory, onlyOne));}u_int8_t MP4Atom::GetVersion(){    if (strcmp("version", m_pProperties[0]->GetName())) {        return 0;    }    return ((MP4Integer8Property*)m_pProperties[0])->GetValue();}void MP4Atom::SetVersion(u_int8_t version) {    if (strcmp("version", m_pProperties[0]->GetName())) {        return;    }    ((MP4Integer8Property*)m_pProperties[0])->SetValue(version);}u_int32_t MP4Atom::GetFlags(){    if (strcmp("flags", m_pProperties[1]->GetName())) {        return 0;    }    return ((MP4Integer24Property*)m_pProperties[1])->GetValue();}void MP4Atom::SetFlags(u_int32_t flags) {    if (strcmp("flags", m_pProperties[1]->GetName())) {        return;    }    ((MP4Integer24Property*)m_pProperties[1])->SetValue(flags);}void MP4Atom::Dump(FILE* pFile, u_int8_t indent, bool dumpImplicits){    if (m_type[0] != '\0') {        Indent(pFile, indent);        fprintf(pFile, "type %s\n", m_type);        fflush(pFile);    }    u_int32_t i;    u_int32_t size;    // dump our properties    size = m_pProperties.Size();    for (i = 0; i < size; i++) {        /* skip details of tables unless we're told to be verbose */        if (m_pProperties[i]->GetType() == TableProperty          && !(GetVerbosity() & MP4_DETAILS_TABLE)) {            Indent(pFile, indent + 1);            fprintf(pFile, "<table entries suppressed>\n");            continue;        }        m_pProperties[i]->Dump(pFile, indent + 1, dumpImplicits);    }    // dump our children    size = m_pChildAtoms.Size();    for (i = 0; i < size; i++) {        m_pChildAtoms[i]->Dump(pFile, indent + 1, dumpImplicits);    }}u_int32_t MP4Atom::GetVerbosity() {    ASSERT(m_pFile);    return m_pFile->GetVerbosity();}u_int8_t MP4Atom::GetDepth(){    if (m_depth < 0xFF) {        return m_depth;    }    MP4Atom *pAtom = this;    m_depth = 0;    while ((pAtom = pAtom->GetParentAtom()) != NULL) {        m_depth++;        ASSERT(m_depth < 255);    }    return m_depth;}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?