⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mp4file.cpp

📁 AAC编解码源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
                    pTrack = new MP4RtpHintTrack(this, pTrakAtom);
                } else {
                    pTrack = new MP4Track(this, pTrakAtom);
                }
                m_pTracks.Add(pTrack);
            }
            catch (MP4Error* e) {
                VERBOSE_ERROR(m_verbosity, e->Print());
                delete e;
            }

            // remember when we encounter the OD track
            if (pTrack && !strcmp(pTrack->GetType(), MP4_OD_TRACK_TYPE)) {
                if (m_odTrackId == MP4_INVALID_TRACK_ID) {
                    m_odTrackId = pTrackIdProperty->GetValue();
                } else {
                    VERBOSE_READ(GetVerbosity(),
                        printf("Warning: multiple OD tracks present\n"));
                }
            }
        } else {
            m_trakIds.Add(0);
        }

        trackIndex++;
    }
}

void MP4File::CacheProperties()
{
    FindIntegerProperty("moov.mvhd.modificationTime",
        (MP4Property**)&m_pModificationProperty);

    FindIntegerProperty("moov.mvhd.timeScale",
        (MP4Property**)&m_pTimeScaleProperty);

    FindIntegerProperty("moov.mvhd.duration",
        (MP4Property**)&m_pDurationProperty);
}

void MP4File::BeginWrite()
{
    m_pRootAtom->BeginWrite();
}

void MP4File::FinishWrite()
{
    // for all tracks, flush chunking buffers
    for (u_int32_t i = 0; i < m_pTracks.Size(); i++) {
        ASSERT(m_pTracks[i]);
        m_pTracks[i]->FinishWrite();
    }

    // ask root atom to write
    m_pRootAtom->FinishWrite();

    // check if file shrunk, e.g. we deleted a track
    if (GetSize() < m_orgFileSize) {
        // just use a free atom to mark unused space
        // MP4Optimize() should be used to clean up this space
        MP4Atom* pFreeAtom = MP4Atom::CreateAtom("free");
        ASSERT(pFreeAtom);
        pFreeAtom->SetFile(this);
        pFreeAtom->SetSize((u_int64_t)MAX((int64_t)m_orgFileSize - ((int64_t)m_fileSize + 8), 0));
        pFreeAtom->Write();
        delete pFreeAtom;
    }
}

MP4Duration MP4File::UpdateDuration(MP4Duration duration)
{
    MP4Duration currentDuration = GetDuration();
    if (duration > currentDuration) {
        SetDuration(duration);
        return duration;
    }
    return currentDuration;
}

void MP4File::Dump(FILE* pDumpFile, bool dumpImplicits)
{
    if (pDumpFile == NULL) {
        pDumpFile = stdout;
    }

    fprintf(pDumpFile, "Dumping %s meta-information...\n", m_fileName);
    m_pRootAtom->Dump(pDumpFile, 0, dumpImplicits);
}

void MP4File::Close()
{
    if (m_mode == 'w') {
        SetIntegerProperty("moov.mvhd.modificationTime",
            MP4GetAbsTimestamp());

        FinishWrite();
    }

#ifndef USE_FILE_CALLBACKS
    fclose(m_pFile);
    m_pFile = NULL;
#else
    m_MP4fclose(m_userData);
#endif
}

const char* MP4File::TempFileName()
{
    // there are so many attempts in libc to get this right
    // that for portablity reasons, it's best just to roll our own
#ifndef _WIN32
    static char tempFileName[64];
    u_int32_t i;
    for (i = getpid(); i < 0xFFFFFFFF; i++) {
        sprintf(tempFileName, "./tmp%u.mp4", i);
        if (access(tempFileName, F_OK) != 0) {
            break;
        }
    }
    if (i == 0xFFFFFFFF) {
        throw new MP4Error("can't create temporary file", "TempFileName");
    }
#else
    static char tempFileName[MAX_PATH + 3];
    GetTempFileName(".", // dir. for temp. files
                    "mp4",                // temp. filename prefix
                    0,                    // create unique name
                    tempFileName);        // buffer for name
#endif

    return tempFileName;
}

void MP4File::Rename(const char* oldFileName, const char* newFileName)
{
    int rc;

#ifdef _WIN32
    rc = remove(newFileName);
    if (rc == 0) {
        rc = rename(oldFileName, newFileName);
    }
    else
        remove(oldFileName);

#else
    rc = rename(oldFileName, newFileName);
#endif
    if (rc != 0) {
        throw new MP4Error(errno, "can't overwrite existing file", "Rename");
    }
}

void MP4File::ProtectWriteOperation(char* where)
{
    if (m_mode == 'r') {
        throw new MP4Error("operation not permitted in read mode", where);
    }
}

MP4Track* MP4File::GetTrack(MP4TrackId trackId)
{
    return m_pTracks[FindTrackIndex(trackId)];
}

MP4Atom* MP4File::FindAtom(const char* name)
{
    MP4Atom* pAtom = NULL;
    if (!name || !strcmp(name, "")) {
        pAtom = m_pRootAtom;
    } else {
        pAtom = m_pRootAtom->FindAtom(name);
    }
    return pAtom;
}

MP4Atom* MP4File::AddChildAtom(
    const char* parentName,
    const char* childName)
{
    return AddChildAtom(FindAtom(parentName), childName);
}

MP4Atom* MP4File::AddChildAtom(
    MP4Atom* pParentAtom,
    const char* childName)
{
    return InsertChildAtom(pParentAtom, childName,
        pParentAtom->GetNumberOfChildAtoms());
}

MP4Atom* MP4File::InsertChildAtom(
    const char* parentName,
    const char* childName,
    u_int32_t index)
{
    return InsertChildAtom(FindAtom(parentName), childName, index);
}

MP4Atom* MP4File::InsertChildAtom(
    MP4Atom* pParentAtom,
    const char* childName,
    u_int32_t index)
{
    MP4Atom* pChildAtom = MP4Atom::CreateAtom(childName);

    ASSERT(pParentAtom);
    pParentAtom->InsertChildAtom(pChildAtom, index);

    pChildAtom->Generate();

    return pChildAtom;
}

MP4Atom* MP4File::AddDescendantAtoms(
    const char* ancestorName,
    const char* descendantNames)
{
    return AddDescendantAtoms(FindAtom(ancestorName), descendantNames);
}

MP4Atom* MP4File::AddDescendantAtoms(
    MP4Atom* pAncestorAtom, const char* descendantNames)
{
    ASSERT(pAncestorAtom);

    MP4Atom* pParentAtom = pAncestorAtom;
    MP4Atom* pChildAtom = NULL;

    while (true) {
        char* childName = MP4NameFirst(descendantNames);

        if (childName == NULL) {
            break;
        }

        descendantNames = MP4NameAfterFirst(descendantNames);

        pChildAtom = pParentAtom->FindChildAtom(childName);

        if (pChildAtom == NULL) {
            pChildAtom = AddChildAtom(pParentAtom, childName);
        }

        pParentAtom = pChildAtom;

        MP4Free(childName);
    }

    return pChildAtom;
}

bool MP4File::FindProperty(const char* name,
    MP4Property** ppProperty, u_int32_t* pIndex)
{
    if (pIndex) {
        *pIndex = 0;    // set the default answer for index
    }

    return m_pRootAtom->FindProperty(name, ppProperty, pIndex);
}

void MP4File::FindIntegerProperty(const char* name,
    MP4Property** ppProperty, u_int32_t* pIndex)
{
    if (!FindProperty(name, ppProperty, pIndex)) {
        throw new MP4Error("no such property - %s", "MP4File::FindIntegerProperty", name);
    }

    switch ((*ppProperty)->GetType()) {
    case Integer8Property:
    case Integer16Property:
    case Integer24Property:
    case Integer32Property:
    case Integer64Property:
        break;
    default:
      throw new MP4Error("type mismatch - property %s type %d", "MP4File::FindIntegerProperty", name, (*ppProperty)->GetType());
    }
}

u_int64_t MP4File::GetIntegerProperty(const char* name)
{
    MP4Property* pProperty;
    u_int32_t index;

    FindIntegerProperty(name, &pProperty, &index);

    return ((MP4IntegerProperty*)pProperty)->GetValue(index);
}

void MP4File::SetIntegerProperty(const char* name, u_int64_t value)
{
    ProtectWriteOperation("SetIntegerProperty");

    MP4Property* pProperty = NULL;
    u_int32_t index = 0;

    FindIntegerProperty(name, &pProperty, &index);

    ((MP4IntegerProperty*)pProperty)->SetValue(value, index);
}

void MP4File::FindFloatProperty(const char* name,
    MP4Property** ppProperty, u_int32_t* pIndex)
{
    if (!FindProperty(name, ppProperty, pIndex)) {
        throw new MP4Error("no such property - %s", "MP4File::FindFloatProperty", name);
    }
    if ((*ppProperty)->GetType() != Float32Property) {
        throw new MP4Error("type mismatch - property %s type %d",
                   "MP4File::FindFloatProperty",
                   name,
                   (*ppProperty)->GetType());
    }
}

float MP4File::GetFloatProperty(const char* name)
{
    MP4Property* pProperty;
    u_int32_t index;

    FindFloatProperty(name, &pProperty, &index);

    return ((MP4Float32Property*)pProperty)->GetValue(index);
}

void MP4File::SetFloatProperty(const char* name, float value)
{
    ProtectWriteOperation("SetFloatProperty");

    MP4Property* pProperty;
    u_int32_t index;

    FindFloatProperty(name, &pProperty, &index);

    ((MP4Float32Property*)pProperty)->SetValue(value, index);
}

void MP4File::FindStringProperty(const char* name,
    MP4Property** ppProperty, u_int32_t* pIndex)
{
    if (!FindProperty(name, ppProperty, pIndex)) {
        throw new MP4Error("no such property - %s", "MP4File::FindStringProperty", name);
    }
    if ((*ppProperty)->GetType() != StringProperty) {
        throw new MP4Error("type mismatch - property %s type %d", "MP4File::FindStringProperty",
                   name, (*ppProperty)->GetType());
    }
}

const char* MP4File::GetStringProperty(const char* name)
{
    MP4Property* pProperty;
    u_int32_t index;

    FindStringProperty(name, &pProperty, &index);

    return ((MP4StringProperty*)pProperty)->GetValue(index);
}

void MP4File::SetStringProperty(const char* name, const char* value)
{
    ProtectWriteOperation("SetStringProperty");

    MP4Property* pProperty;
    u_int32_t index;

    FindStringProperty(name, &pProperty, &index);

    ((MP4StringProperty*)pProperty)->SetValue(value, index);
}

void MP4File::FindBytesProperty(const char* name,
    MP4Property** ppProperty, u_int32_t* pIndex)
{
    if (!FindProperty(name, ppProperty, pIndex)) {
        throw new MP4Error("no such property %s", "MP4File::FindBytesProperty", name);
    }
    if ((*ppProperty)->GetType() != BytesProperty) {
        throw new MP4Error("type mismatch - property %s - type %d", "MP4File::FindBytesProperty", name, (*ppProperty)->GetType());
    }
}

void MP4File::GetBytesProperty(const char* name,
    u_int8_t** ppValue, u_int32_t* pValueSize)
{
    MP4Property* pProperty;
    u_int32_t index;

    FindBytesProperty(name, &pProperty, &index);

    ((MP4BytesProperty*)pProperty)->GetValue(ppValue, pValueSize, index);
}

void MP4File::SetBytesProperty(const char* name,
    const u_int8_t* pValue, u_int32_t valueSize)
{
    ProtectWriteOperation("SetBytesProperty");

    MP4Property* pProperty;
    u_int32_t index;

    FindBytesProperty(name, &pProperty, &index);

    ((MP4BytesProperty*)pProperty)->SetValue(pValue, valueSize, index);
}


// track functions

MP4TrackId MP4File::AddTrack(const char* type, u_int32_t timeScale)
{
    ProtectWriteOperation("AddTrack");

    // create and add new trak atom
    MP4Atom* pTrakAtom = AddChildAtom("moov", "trak");

    // allocate a new track id
    MP4TrackId trackId = AllocTrackId();

    m_trakIds.Add(trackId);

    // set track id
    MP4Integer32Property* pInteger32Property = NULL;
    pTrakAtom->FindProperty(
        "trak.tkhd.trackId", (MP4Property**)&pInteger32Property);
    ASSERT(pInteger32Property);
    pInteger32Property->SetValue(trackId);

    // set track type
    const char* normType = MP4Track::NormalizeTrackType(type);

    // sanity check for user defined types
    if (strlen(normType) > 4) {
        VERBOSE_WARNING(m_verbosity,
            printf("AddTrack: type truncated to four characters\n"));
        // StringProperty::SetValue() will do the actual truncation
    }

    MP4StringProperty* pStringProperty = NULL;
    pTrakAtom->FindProperty(
        "trak.mdia.hdlr.handlerType", (MP4Property**)&pStringProperty);
    ASSERT(pStringProperty);
    pStringProperty->SetValue(normType);

    // set track time scale
    pInteger32Property = NULL;
    pTrakAtom->FindProperty(
        "trak.mdia.mdhd.timeScale", (MP4Property**)&pInteger32Property);
    ASSERT(pInteger32Property);

⌨️ 快捷键说明

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