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

📄 mp4track.cpp

📁 6410BSP1
💻 CPP
📖 第 1 页 / 共 4 页
字号:
void MP4Track::UpdateChunkOffsets(u_int64_t chunkOffset){    if (m_pChunkOffsetProperty->GetType() == Integer32Property) {        ((MP4Integer32Property*)m_pChunkOffsetProperty)->AddValue(chunkOffset);    } else {        ((MP4Integer64Property*)m_pChunkOffsetProperty)->AddValue(chunkOffset);    }    m_pChunkCountProperty->IncrementValue();}MP4Duration MP4Track::GetFixedSampleDuration(){    u_int32_t numStts = m_pSttsCountProperty->GetValue();    if (numStts == 0) {        return m_fixedSampleDuration;    }    if (numStts != 1) {        return MP4_INVALID_DURATION;    // sample duration is not fixed    }    return m_pSttsSampleDeltaProperty->GetValue(0);}bool MP4Track::SetFixedSampleDuration(MP4Duration duration){    u_int32_t numStts = m_pSttsCountProperty->GetValue();    // setting this is only allowed before samples have been written    if (numStts != 0) {        return false;    }    m_fixedSampleDuration = duration;    return true;}void MP4Track::GetSampleTimes(MP4SampleId sampleId,    MP4Timestamp* pStartTime, MP4Duration* pDuration){    u_int32_t numStts = m_pSttsCountProperty->GetValue();    MP4SampleId sid = 1;    MP4Duration elapsed = 0;    for (u_int32_t sttsIndex = 0; sttsIndex < numStts; sttsIndex++) {        u_int32_t sampleCount =             m_pSttsSampleCountProperty->GetValue(sttsIndex);        u_int32_t sampleDelta =             m_pSttsSampleDeltaProperty->GetValue(sttsIndex);        if (sampleId <= sid + sampleCount - 1) {            if (pStartTime) {              *pStartTime = (sampleId - sid);              *pStartTime *= sampleDelta;              *pStartTime += elapsed;            }            if (pDuration) {                *pDuration = sampleDelta;            }            return;        }        sid += sampleCount;        elapsed += sampleCount * sampleDelta;    }    throw new MP4Error("sample id out of range",         "MP4Track::GetSampleTimes");}MP4SampleId MP4Track::GetSampleIdFromTime(    MP4Timestamp when,     bool wantSyncSample) {    u_int32_t numStts = m_pSttsCountProperty->GetValue();    MP4SampleId sid = 1;    MP4Duration elapsed = 0;    for (u_int32_t sttsIndex = 0; sttsIndex < numStts; sttsIndex++) {        u_int32_t sampleCount =             m_pSttsSampleCountProperty->GetValue(sttsIndex);        u_int32_t sampleDelta =             m_pSttsSampleDeltaProperty->GetValue(sttsIndex);        if (sampleDelta == 0 && sttsIndex < numStts - 1) {            VERBOSE_READ(m_pFile->GetVerbosity(),                printf("Warning: Zero sample duration, stts entry %u\n",                sttsIndex));        }        MP4Duration d = when - elapsed;        if (d <= sampleCount * sampleDelta) {            MP4SampleId sampleId = sid;            if (sampleDelta) {                sampleId += (d / sampleDelta);            }            if (wantSyncSample) {                return GetNextSyncSample(sampleId);            }            return sampleId;        }        sid += sampleCount;        elapsed += sampleCount * sampleDelta;    }    throw new MP4Error("time out of range",         "MP4Track::GetSampleIdFromTime");    return 0; // satisfy MS compiler}void MP4Track::UpdateSampleTimes(MP4Duration duration){    u_int32_t numStts = m_pSttsCountProperty->GetValue();    // if duration == duration of last entry    if (numStts       && duration == m_pSttsSampleDeltaProperty->GetValue(numStts-1)) {        // increment last entry sampleCount        m_pSttsSampleCountProperty->IncrementValue(1, numStts-1);    } else {        // add stts entry, sampleCount = 1, sampleDuration = duration        m_pSttsSampleCountProperty->AddValue(1);        m_pSttsSampleDeltaProperty->AddValue(duration);        m_pSttsCountProperty->IncrementValue();;    }}u_int32_t MP4Track::GetSampleCttsIndex(MP4SampleId sampleId,     MP4SampleId* pFirstSampleId){    u_int32_t numCtts = m_pCttsCountProperty->GetValue();    MP4SampleId sid = 1;        for (u_int32_t cttsIndex = 0; cttsIndex < numCtts; cttsIndex++) {        u_int32_t sampleCount =             m_pCttsSampleCountProperty->GetValue(cttsIndex);        if (sampleId <= sid + sampleCount - 1) {            if (pFirstSampleId) {                *pFirstSampleId = sid;            }            return cttsIndex;        }        sid += sampleCount;    }    throw new MP4Error("sample id out of range",         "MP4Track::GetSampleCttsIndex");    return 0; // satisfy MS compiler}MP4Duration MP4Track::GetSampleRenderingOffset(MP4SampleId sampleId){    if (m_pCttsCountProperty == NULL) {        return 0;    }    if (m_pCttsCountProperty->GetValue() == 0) {        return 0;    }    u_int32_t cttsIndex = GetSampleCttsIndex(sampleId);    return m_pCttsSampleOffsetProperty->GetValue(cttsIndex);}void MP4Track::UpdateRenderingOffsets(MP4SampleId sampleId,     MP4Duration renderingOffset){    // if ctts atom doesn't exist    if (m_pCttsCountProperty == NULL) {        // no rendering offset, so nothing to do        if (renderingOffset == 0) {            return;        }        // else create a ctts atom        MP4Atom* pCttsAtom = AddAtom("trak.mdia.minf.stbl", "ctts");        // and get handles on the properties        pCttsAtom->FindProperty(            "ctts.entryCount",            (MP4Property**)&m_pCttsCountProperty);        pCttsAtom->FindProperty(            "ctts.entries.sampleCount",            (MP4Property**)&m_pCttsSampleCountProperty);        pCttsAtom->FindProperty(            "ctts.entries.sampleOffset",            (MP4Property**)&m_pCttsSampleOffsetProperty);        // if this is not the first sample        if (sampleId > 1) {            // add a ctts entry for all previous samples            // with rendering offset equal to zero            m_pCttsSampleCountProperty->AddValue(sampleId - 1);            m_pCttsSampleOffsetProperty->AddValue(0);            m_pCttsCountProperty->IncrementValue();;        }    }    // ctts atom exists (now)    u_int32_t numCtts = m_pCttsCountProperty->GetValue();    // if renderingOffset == renderingOffset of last entry    if (numCtts && renderingOffset       == m_pCttsSampleOffsetProperty->GetValue(numCtts-1)) {        // increment last entry sampleCount        m_pCttsSampleCountProperty->IncrementValue(1, numCtts-1);    } else {        // add ctts entry, sampleCount = 1, sampleOffset = renderingOffset        m_pCttsSampleCountProperty->AddValue(1);        m_pCttsSampleOffsetProperty->AddValue(renderingOffset);        m_pCttsCountProperty->IncrementValue();    }}void MP4Track::SetSampleRenderingOffset(MP4SampleId sampleId,     MP4Duration renderingOffset){    // check if any ctts entries exist    if (m_pCttsCountProperty == NULL      || m_pCttsCountProperty->GetValue() == 0) {        // if not then Update routine can be used         // to create a ctts entry for samples before this one        // and a ctts entry for this sample         UpdateRenderingOffsets(sampleId, renderingOffset);        // but we also need a ctts entry         // for all samples after this one        u_int32_t afterSamples = GetNumberOfSamples() - sampleId;        if (afterSamples) {            m_pCttsSampleCountProperty->AddValue(afterSamples);            m_pCttsSampleOffsetProperty->AddValue(0);            m_pCttsCountProperty->IncrementValue();;        }        return;    }    MP4SampleId firstSampleId;    u_int32_t cttsIndex = GetSampleCttsIndex(sampleId, &firstSampleId);    // do nothing in the degenerate case    if (renderingOffset ==       m_pCttsSampleOffsetProperty->GetValue(cttsIndex)) {        return;    }    u_int32_t sampleCount =        m_pCttsSampleCountProperty->GetValue(cttsIndex);    // if this sample has it's own ctts entry    if (sampleCount == 1) {        // then just set the value,         // note we don't attempt to collapse entries        m_pCttsSampleOffsetProperty->SetValue(renderingOffset, cttsIndex);        return;    }    MP4SampleId lastSampleId = firstSampleId + sampleCount - 1;    // else we share this entry with other samples    // we need to insert our own entry    if (sampleId == firstSampleId) {        // our sample is the first one        m_pCttsSampleCountProperty->            InsertValue(1, cttsIndex);        m_pCttsSampleOffsetProperty->            InsertValue(renderingOffset, cttsIndex);        m_pCttsSampleCountProperty->            SetValue(sampleCount - 1, cttsIndex + 1);        m_pCttsCountProperty->IncrementValue();    } else if (sampleId == lastSampleId) {        // our sample is the last one        m_pCttsSampleCountProperty->            InsertValue(1, cttsIndex + 1);        m_pCttsSampleOffsetProperty->            InsertValue(renderingOffset, cttsIndex + 1);        m_pCttsSampleCountProperty->            SetValue(sampleCount - 1, cttsIndex);        m_pCttsCountProperty->IncrementValue();    } else {        // our sample is in the middle, UGH!        // insert our new entry        m_pCttsSampleCountProperty->            InsertValue(1, cttsIndex + 1);        m_pCttsSampleOffsetProperty->            InsertValue(renderingOffset, cttsIndex + 1);        // adjust count of previous entry        m_pCttsSampleCountProperty->            SetValue(sampleId - firstSampleId, cttsIndex);        // insert new entry for those samples beyond our sample        m_pCttsSampleCountProperty->            InsertValue(lastSampleId - sampleId, cttsIndex + 2);        u_int32_t oldRenderingOffset =            m_pCttsSampleOffsetProperty->GetValue(cttsIndex);        m_pCttsSampleOffsetProperty->            InsertValue(oldRenderingOffset, cttsIndex + 2);        m_pCttsCountProperty->IncrementValue(2);    }}bool MP4Track::IsSyncSample(MP4SampleId sampleId){    if (m_pStssCountProperty == NULL) {        return true;    }    u_int32_t numStss = m_pStssCountProperty->GetValue();        for (u_int32_t stssIndex = 0; stssIndex < numStss; stssIndex++) {        MP4SampleId syncSampleId =             m_pStssSampleProperty->GetValue(stssIndex);        if (sampleId == syncSampleId) {            return true;        }         if (sampleId < syncSampleId) {            break;        }    }    return false;}// N.B. "next" is inclusive of this sample idMP4SampleId MP4Track::GetNextSyncSample(MP4SampleId sampleId){    if (m_pStssCountProperty == NULL) {        return sampleId;    }    u_int32_t numStss = m_pStssCountProperty->GetValue();        for (u_int32_t stssIndex = 0; stssIndex < numStss; stssIndex++) {        MP4SampleId syncSampleId =             m_pStssSampleProperty->GetValue(stssIndex);        if (sampleId > syncSampleId) {            continue;        }        return syncSampleId;    }    // LATER check stsh for alternate sample    return MP4_INVALID_SAMPLE_ID;}void MP4Track::UpdateSyncSamples(MP4SampleId sampleId, bool isSyncSample){    if (isSyncSample) {        // if stss atom exists, add entry        if (m_pStssCountProperty) {            m_pStssSampleProperty->AddValue(sampleId);            m_pStssCountProperty->IncrementValue();        } // else nothing to do (yet)    } else { // !isSyncSample        // if stss atom doesn't exist, create one        if (m_pStssCountProperty == NULL) {            MP4Atom* pStssAtom = AddAtom("trak.mdia.minf.stbl", "stss");            pStssAtom->FindProperty(                "stss.entryCount",                (MP4Property**)&m_pStssCountProperty);            pStssAtom->FindProperty(                "stss.entries.sampleNumber",                (MP4Property**)&m_pStssSampleProperty);            // set values for all samples that came before this one            for (MP4SampleId sid = 1; sid < sampleId; sid++) {                m_pStssSampleProperty->AddValue(sid);                m_pStssCountProperty->IncrementValue();            }        } // else nothing to do    }}MP4Atom* MP4Track::AddAtom(char* parentName, char* childName){    MP4Atom* pChildAtom = MP4Atom::CreateAtom(childName);    MP4Atom* pParentAtom = m_pTrakAtom->FindAtom(parentName);    ASSERT(pParentAtom);    pParentAtom->AddChildAtom(pChildAtom);    pChildAtom->Generate();    return pChildAtom;}u_int64_t MP4Track::GetDuration(){    return m_pMediaDurationProperty->GetValue();}u_int32_t MP4Track::GetTimeScale(){    return m_pTimeScaleProperty->GetValue();}void MP4Track::UpdateDurations(MP4Duration duration){    // update media, track, and movie durations

⌨️ 快捷键说明

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