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

📄 mp4file.cpp

📁 6410BSP1
💻 CPP
📖 第 1 页 / 共 5 页
字号:
#ifdef O_LARGEFILE    // UGH! fopen doesn't open a file in 64-bit mode, period.    // So we need to use open() and then fdopen()    int fd;    int flags = O_LARGEFILE;    if (strchr(fmode, '+')) {        flags |= O_CREAT | O_RDWR;        if (fmode[0] == 'w') {            flags |= O_TRUNC;        }    } else {        if (fmode[0] == 'w') {            flags |= O_CREAT | O_TRUNC | O_WRONLY;        } else {            flags |= O_RDONLY;        }    }    fd = open(m_fileName, flags, 0666);     if (fd >= 0) {        m_pFile = fdopen(fd, fmode);    }#else    m_pFile = fopen(m_fileName, fmode);#endif    if (m_pFile == NULL) {#ifdef SIMON_CHANGED        printf("\n[%s]  %s", "MP4Open", "failed");        RaiseException(1, 0, 0, NULL);#else        throw new MP4Error(errno, "failed", "MP4Open");#endif    }    if (m_mode == 'r') {#ifdef SIMON_CHANGED    // Simon Chun        fseek(m_pFile, 0L, SEEK_END);        m_orgFileSize = m_fileSize = ftell(m_pFile);        fseek(m_pFile, 0L, SEEK_SET);#else        struct stat s;        if (fstat(fileno(m_pFile), &s) < 0) {            throw new MP4Error(errno, "stat failed", "MP4Open");        }        m_orgFileSize = m_fileSize = s.st_size;#endif    } else {        m_orgFileSize = m_fileSize = 0;    }}#ifdef _WIN32void MP4File::Open(const wchar_t* fmode){    ASSERT(m_pFile == NULL);#ifdef O_LARGEFILE    // UGH! fopen doesn't open a file in 64-bit mode, period.    // So we need to use open() and then fdopen()    int fd;    int flags = O_LARGEFILE;    if (strchr(fmode, '+')) {        flags |= O_CREAT | O_RDWR;        if (fmode[0] == 'w') {            flags |= O_TRUNC;        }    } else {        if (fmode[0] == 'w') {            flags |= O_CREAT | O_TRUNC | O_WRONLY;        } else {            flags |= O_RDONLY;        }    }    fd = _wopen(m_fileName_w, flags, 0666);    if (fd >= 0) {        m_pFile = _wfdopen(fd, fmode);    }#else    m_pFile = _wfopen(m_fileName_w, fmode);#endif    if (m_pFile == NULL) {#ifdef SIMON_CHANGED        printf("\n[%s]  %s", "MP4Open", "failed");        RaiseException(1, 0, 0, NULL);#else        throw new MP4Error(errno, "failed", "MP4Open");#endif    }    if (m_mode == 'r') {#ifdef SIMON_CHANGED    // Simon Chun        fseek(m_pFile, 0L, SEEK_END);        m_orgFileSize = m_fileSize = ftell(m_pFile);        fseek(m_pFile, 0L, SEEK_SET);#else        struct stat s;        if (fstat(fileno(m_pFile), &s) < 0) {            throw new MP4Error(errno, "stat failed", "MP4Open");        }        m_orgFileSize = m_fileSize = s.st_size;#endif    } else {        m_orgFileSize = m_fileSize = 0;    }}#endifvoid MP4File::ReadFromFile(){    // ensure we start at beginning of file    SetPosition(0);    // create a new root atom    ASSERT(m_pRootAtom == NULL);    m_pRootAtom = MP4Atom::CreateAtom(NULL);    u_int64_t fileSize = GetSize();    m_pRootAtom->SetFile(this);    m_pRootAtom->SetStart(0);    m_pRootAtom->SetSize(fileSize);    m_pRootAtom->SetEnd(fileSize);    m_pRootAtom->Read();    // create MP4Track's for any tracks in the file    GenerateTracks();}void MP4File::GenerateTracks(){    u_int32_t trackIndex = 0;    while (true) {        char trackName[32];        snprintf(trackName, sizeof(trackName), "moov.trak[%u]", trackIndex);        // find next trak atom        MP4Atom* pTrakAtom = m_pRootAtom->FindAtom(trackName);        // done, no more trak atoms        if (pTrakAtom == NULL) {            break;        }        // find track id property        MP4Integer32Property* pTrackIdProperty = NULL;        pTrakAtom->FindProperty(            "trak.tkhd.trackId",            (MP4Property**)&pTrackIdProperty);        // find track type property        MP4StringProperty* pTypeProperty = NULL;        pTrakAtom->FindProperty(            "trak.mdia.hdlr.handlerType",            (MP4Property**)&pTypeProperty);        // ensure we have the basics properties        if (pTrackIdProperty && pTypeProperty) {            m_trakIds.Add(pTrackIdProperty->GetValue());            MP4Track* pTrack = NULL;            __try {                if (!strcmp(pTypeProperty->GetValue(), MP4_HINT_TRACK_TYPE)) {                    pTrack = new MP4RtpHintTrack(this, pTrakAtom);                } else {                    pTrack = new MP4Track(this, pTrakAtom);                }                m_pTracks.Add(pTrack);            }            __except (EXCEPTION_EXECUTE_HANDLER) {//                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);        int64_t size = m_orgFileSize - (m_fileSize + 8);        if (size < 0) size = 0;        pFreeAtom->SetSize(size);        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();    }    fclose(m_pFile);    m_pFile = NULL;}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#ifdef SIMON_CHANGED    wchar_t   tmpfile_wchar[256];    GetTempFileName(L".", // dir. for temp. files                     L"mp4",                // temp. filename prefix                     0,                    // create unique name                     tmpfile_wchar);        // buffer for name     wchar_t2char(tmpfile_wchar, m_tempFileName);#else#ifndef _WIN32    u_int32_t i;    for (i = getpid(); i < 0xFFFFFFFF; i++) {        sprintf(m_tempFileName, "./tmp%u.mp4", i);        if (access(m_tempFileName, F_OK) != 0) {            break;        }    }    if (i == 0xFFFFFFFF) {        throw new MP4Error("can't create temporary file", "TempFileName");    }#else    GetTempFileName(".", // dir. for temp. files                     "mp4",                // temp. filename prefix                     0,                    // create unique name                     m_tempFileName);        // buffer for name #endif#endif /* SIMON_CHANGED */    return m_tempFileName;}void MP4File::Rename(const char* oldFileName, const char* newFileName){    int rc;#ifdef SIMON_CHANGED    wchar_t   old_wchar[256], new_wchar[256];    char2wchar_t(newFileName, new_wchar);    char2wchar_t(oldFileName, old_wchar);    DeleteFile(new_wchar);    if (MoveFile(old_wchar, new_wchar))        rc = 0;    else        rc = 1;#else#ifdef _WIN32    rc = remove(newFileName);    if (rc == 0) {        rc = rename(oldFileName, newFileName);    }#else    rc = rename(oldFileName, newFileName);#endif#endif /* SIMON_CHANGED */    if (rc != 0) {//        throw new MP4Error(errno, "can't overwrite existing file", "Rename");        RaiseException(1, 0, 0, NULL);    }}void MP4File::ProtectWriteOperation(char* where){    if (m_mode == 'r') {//        throw new MP4Error("operation not permitted in read mode", where);        RaiseException(1, 0, 0, NULL);    }}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)) {#ifdef SIMON_CHANGED        printf("\n[%s]  %s - %s", "MP4File::FindIntegerProperty", "no such property", name);        RaiseException(1, 0, 0, NULL);#else        throw new MP4Error("no such property - %s", "MP4File::FindIntegerProperty", name);

⌨️ 快捷键说明

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