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

📄 mp4track.cpp

📁 6410BSP1
💻 CPP
📖 第 1 页 / 共 4 页
字号:
    m_pMediaDurationProperty->SetValue(        m_pMediaDurationProperty->GetValue() + duration);    MP4Duration movieDuration = ToMovieDuration(duration);    m_pTrackDurationProperty->SetValue(        m_pTrackDurationProperty->GetValue() + movieDuration);    m_pFile->UpdateDuration(m_pTrackDurationProperty->GetValue());}MP4Duration MP4Track::ToMovieDuration(MP4Duration trackDuration){    return (trackDuration * m_pFile->GetTimeScale())         / m_pTimeScaleProperty->GetValue();}void MP4Track::UpdateModificationTimes(){    // update media and track modification times    MP4Timestamp now = MP4GetAbsTimestamp();    m_pMediaModificationProperty->SetValue(now);    m_pTrackModificationProperty->SetValue(now);}u_int32_t MP4Track::GetNumberOfChunks(){    return m_pChunkOffsetProperty->GetCount();}u_int32_t MP4Track::GetChunkStscIndex(MP4ChunkId chunkId){    u_int32_t stscIndex;    u_int32_t numStscs = m_pStscCountProperty->GetValue();    ASSERT(chunkId);    ASSERT(numStscs > 0);    for (stscIndex = 0; stscIndex < numStscs; stscIndex++) {        if (chunkId < m_pStscFirstChunkProperty->GetValue(stscIndex)) {            ASSERT(stscIndex != 0);            break;        }    }    return stscIndex - 1;}MP4Timestamp MP4Track::GetChunkTime(MP4ChunkId chunkId){    u_int32_t stscIndex = GetChunkStscIndex(chunkId);    MP4ChunkId firstChunkId =         m_pStscFirstChunkProperty->GetValue(stscIndex);    MP4SampleId firstSample =         m_pStscFirstSampleProperty->GetValue(stscIndex);    u_int32_t samplesPerChunk =         m_pStscSamplesPerChunkProperty->GetValue(stscIndex);    MP4SampleId firstSampleInChunk =         firstSample + ((chunkId - firstChunkId) * samplesPerChunk);    MP4Timestamp chunkTime;    GetSampleTimes(firstSampleInChunk, &chunkTime, NULL);    return chunkTime;}u_int32_t MP4Track::GetChunkSize(MP4ChunkId chunkId){    u_int32_t stscIndex = GetChunkStscIndex(chunkId);    MP4ChunkId firstChunkId =         m_pStscFirstChunkProperty->GetValue(stscIndex);    MP4SampleId firstSample =         m_pStscFirstSampleProperty->GetValue(stscIndex);    u_int32_t samplesPerChunk =         m_pStscSamplesPerChunkProperty->GetValue(stscIndex);    MP4SampleId firstSampleInChunk =         firstSample + ((chunkId - firstChunkId) * samplesPerChunk);    // need cumulative sizes of samples in chunk     u_int32_t chunkSize = 0;    for (u_int32_t i = 0; i < samplesPerChunk; i++) {        chunkSize += GetSampleSize(firstSampleInChunk + i);    }    return chunkSize;}void MP4Track::ReadChunk(MP4ChunkId chunkId,     u_int8_t** ppChunk, u_int32_t* pChunkSize){    ASSERT(chunkId);    ASSERT(ppChunk);    ASSERT(pChunkSize);    u_int64_t chunkOffset =         m_pChunkOffsetProperty->GetValue(chunkId - 1);    *pChunkSize = GetChunkSize(chunkId);    *ppChunk = (u_int8_t*)MP4Malloc(*pChunkSize);    VERBOSE_READ_SAMPLE(m_pFile->GetVerbosity(),        printf("ReadChunk: track %u id %u offset 0x"X64" size %u (0x%x)\n",            m_trackId, chunkId, chunkOffset, *pChunkSize, *pChunkSize));    u_int64_t oldPos = m_pFile->GetPosition(); // only used in mode == 'w'    __try {        m_pFile->SetPosition(chunkOffset);        m_pFile->ReadBytes(*ppChunk, *pChunkSize);    }    __except (EXCEPTION_EXECUTE_HANDLER) {        // let's not leak memory        MP4Free(*ppChunk);        *ppChunk = NULL;        if (m_pFile->GetMode() == 'w') {            m_pFile->SetPosition(oldPos);        }//        throw e;    }    if (m_pFile->GetMode() == 'w') {        m_pFile->SetPosition(oldPos);    }}void MP4Track::RewriteChunk(MP4ChunkId chunkId,     u_int8_t* pChunk, u_int32_t chunkSize){    u_int64_t chunkOffset = m_pFile->GetPosition();    m_pFile->WriteBytes(pChunk, chunkSize);    m_pChunkOffsetProperty->SetValue(chunkOffset, chunkId - 1);    VERBOSE_WRITE_SAMPLE(m_pFile->GetVerbosity(),        printf("RewriteChunk: track %u id %u offset 0x"X64" size %u (0x%x)\n",            m_trackId, chunkId, chunkOffset, chunkSize, chunkSize)); }// map track type name aliases to official namesbool MP4Track::InitEditListProperties(){    m_pElstCountProperty = NULL;    m_pElstMediaTimeProperty = NULL;    m_pElstDurationProperty = NULL;    m_pElstRateProperty = NULL;    m_pElstReservedProperty = NULL;    MP4Atom* pElstAtom =        m_pTrakAtom->FindAtom("trak.edts.elst");    if (!pElstAtom) {        return false;    }    pElstAtom->FindProperty(        "elst.entryCount",        (MP4Property**)&m_pElstCountProperty);    pElstAtom->FindProperty(        "elst.entries.mediaTime",        (MP4Property**)&m_pElstMediaTimeProperty);    pElstAtom->FindProperty(        "elst.entries.segmentDuration",        (MP4Property**)&m_pElstDurationProperty);    pElstAtom->FindProperty(        "elst.entries.mediaRate",        (MP4Property**)&m_pElstRateProperty);    pElstAtom->FindProperty(        "elst.entries.reserved",        (MP4Property**)&m_pElstReservedProperty);    return m_pElstCountProperty        && m_pElstMediaTimeProperty        && m_pElstDurationProperty        && m_pElstRateProperty        && m_pElstReservedProperty;}MP4EditId MP4Track::AddEdit(MP4EditId editId){    if (!m_pElstCountProperty) {        m_pFile->AddDescendantAtoms(m_pTrakAtom, "edts.elst");        InitEditListProperties();    }    if (editId == MP4_INVALID_EDIT_ID) {        editId = m_pElstCountProperty->GetValue() + 1;    }    m_pElstMediaTimeProperty->InsertValue(0, editId - 1);    m_pElstDurationProperty->InsertValue(0, editId - 1);    m_pElstRateProperty->InsertValue(1, editId - 1);    m_pElstReservedProperty->InsertValue(0, editId - 1);    m_pElstCountProperty->IncrementValue();    return editId;}void MP4Track::DeleteEdit(MP4EditId editId){    if (editId == MP4_INVALID_EDIT_ID) {        throw new MP4Error("edit id can't be zero",             "MP4Track::DeleteEdit");    }    if (!m_pElstCountProperty      || m_pElstCountProperty->GetValue() == 0) {        throw new MP4Error("no edits exist",             "MP4Track::DeleteEdit");    }    m_pElstMediaTimeProperty->DeleteValue(editId - 1);    m_pElstDurationProperty->DeleteValue(editId - 1);    m_pElstRateProperty->DeleteValue(editId - 1);    m_pElstReservedProperty->DeleteValue(editId - 1);    m_pElstCountProperty->IncrementValue(-1);    // clean up if last edit is deleted    if (m_pElstCountProperty->GetValue() == 0) {        m_pElstCountProperty = NULL;        m_pElstMediaTimeProperty = NULL;        m_pElstDurationProperty = NULL;        m_pElstRateProperty = NULL;        m_pElstReservedProperty = NULL;        m_pTrakAtom->DeleteChildAtom(            m_pTrakAtom->FindAtom("trak.edts"));    }}MP4Timestamp MP4Track::GetEditStart(    MP4EditId editId) {    if (editId == MP4_INVALID_EDIT_ID) {        return MP4_INVALID_TIMESTAMP;    } else if (editId == 1) {        return 0;    }    return (MP4Timestamp)GetEditTotalDuration(editId - 1);}    MP4Duration MP4Track::GetEditTotalDuration(    MP4EditId editId){    u_int32_t numEdits = 0;    if (m_pElstCountProperty) {        numEdits = m_pElstCountProperty->GetValue();    }    if (editId == MP4_INVALID_EDIT_ID) {        editId = numEdits;    }    if (numEdits == 0 || editId > numEdits) {        return MP4_INVALID_DURATION;    }    MP4Duration totalDuration = 0;    for (MP4EditId eid = 1; eid <= editId; eid++) {        totalDuration +=             m_pElstDurationProperty->GetValue(eid - 1);    }    return totalDuration;}MP4SampleId MP4Track::GetSampleIdFromEditTime(    MP4Timestamp editWhen,     MP4Timestamp* pStartTime,     MP4Duration* pDuration){    MP4SampleId sampleId = MP4_INVALID_SAMPLE_ID;    u_int32_t numEdits = 0;    if (m_pElstCountProperty) {        numEdits = m_pElstCountProperty->GetValue();    }    if (numEdits) {        MP4Duration editElapsedDuration = 0;        for (MP4EditId editId = 1; editId <= numEdits; editId++) {            // remember edit segment's start time (in edit timeline)            MP4Timestamp editStartTime =                 (MP4Timestamp)editElapsedDuration;            // accumulate edit segment's duration            editElapsedDuration +=                 m_pElstDurationProperty->GetValue(editId - 1);            // calculate difference between the specified edit time            // and the end of this edit segment            if (editElapsedDuration - editWhen <= 0) {                // the specified time has not yet been reached                continue;            }            // 'editWhen' is within this edit segment            // calculate the specified edit time            // relative to just this edit segment            MP4Duration editOffset =                editWhen - editStartTime;            // calculate the media (track) time that corresponds            // to the specified edit time based on the edit list            MP4Timestamp mediaWhen =                 m_pElstMediaTimeProperty->GetValue(editId - 1)                + editOffset;            // lookup the sample id for the media time            sampleId = GetSampleIdFromTime(mediaWhen, false);            // lookup the sample's media start time and duration            MP4Timestamp sampleStartTime;            MP4Duration sampleDuration;            GetSampleTimes(sampleId, &sampleStartTime, &sampleDuration);            // calculate the difference if any between when the sample            // would naturally start and when it starts in the edit timeline             MP4Duration sampleStartOffset =                mediaWhen - sampleStartTime;            // calculate the start time for the sample in the edit time line            MP4Timestamp editSampleStartTime =                editWhen - MIN(editOffset, sampleStartOffset);            MP4Duration editSampleDuration = 0;            // calculate how long this sample lasts in the edit list timeline            if (m_pElstRateProperty->GetValue(editId - 1) == 0) {                // edit segment is a "dwell"                // so sample duration is that of the edit segment                editSampleDuration =                    m_pElstDurationProperty->GetValue(editId - 1);            } else {                // begin with the natural sample duration                editSampleDuration = sampleDuration;                // now shorten that if the edit segment starts                // after the sample would naturally start                 if (editOffset < sampleStartOffset) {                    editSampleDuration -= sampleStartOffset - editOffset;                }                // now shorten that if the edit segment ends                // before the sample would naturally end                if (editElapsedDuration                   < editSampleStartTime + sampleDuration) {                    editSampleDuration -= (editSampleStartTime + sampleDuration)                         - editElapsedDuration;                }            }            if (pStartTime) {                *pStartTime = editSampleStartTime;            }            if (pDuration) {                *pDuration = editSampleDuration;            }            VERBOSE_EDIT(m_pFile->GetVerbosity(),                printf("GetSampleIdFromEditTime: when "U64" "                    "sampleId %u start "U64" duration "D64"\n",                     editWhen, sampleId,                     editSampleStartTime, editSampleDuration));            return sampleId;        }        throw new MP4Error("time out of range",             "MP4Track::GetSampleIdFromEditTime");    } else { // no edit list        sampleId = GetSampleIdFromTime(editWhen, false);        if (pStartTime || pDuration) {            GetSampleTimes(sampleId, pStartTime, pDuration);        }    }    return sampleId;}void MP4Track::CalculateBytesPerSample (){  MP4Atom *pMedia = m_pTrakAtom->FindAtom("trak.mdia.minf.stbl.stsd");  MP4Atom *pMediaData;  const char *media_data_name;  if (pMedia == NULL) return;  if (pMedia->GetNumberOfChildAtoms() != 1) return;    pMediaData = pMedia->GetChildAtom(0);  media_data_name = pMediaData->GetType();  if ((ATOMID(media_data_name) == ATOMID("twos")) ||      (ATOMID(media_data_name) == ATOMID("sowt"))) {    MP4IntegerProperty *chan, *sampleSize;    chan = (MP4IntegerProperty *)pMediaData->GetProperty(4);    sampleSize = (MP4IntegerProperty *)pMediaData->GetProperty(5);    m_bytesPerSample = chan->GetValue() * (sampleSize->GetValue() / 8);  }}  

⌨️ 快捷键说明

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