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

📄 mp4file.cpp

📁 AAC编解码源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
  SetTrackIntegerProperty(trackId,
              "mdia.minf.stbl.stsz.sampleSize", sampleDuration);

  m_pTracks[FindTrackIndex(trackId)]->
    SetFixedSampleDuration(sampleDuration);

  return trackId;
}

MP4TrackId MP4File::AddHintTrack(MP4TrackId refTrackId)
{
    // validate reference track id
    FindTrackIndex(refTrackId);

    MP4TrackId trackId =
        AddTrack(MP4_HINT_TRACK_TYPE, GetTrackTimeScale(refTrackId));

    InsertChildAtom(MakeTrackName(trackId, "mdia.minf"), "hmhd", 0);

    AddChildAtom(MakeTrackName(trackId, "mdia.minf.stbl.stsd"), "rtp ");

    // stsd is a unique beast in that it has a count of the number
    // of child atoms that needs to be incremented after we add the rtp atom
    MP4Integer32Property* pStsdCountProperty;
    FindIntegerProperty(
        MakeTrackName(trackId, "mdia.minf.stbl.stsd.entryCount"),
        (MP4Property**)&pStsdCountProperty);
    pStsdCountProperty->IncrementValue();

    SetTrackIntegerProperty(trackId,
        "mdia.minf.stbl.stsd.rtp .tims.timeScale",
        GetTrackTimeScale(trackId));

    AddDescendantAtoms(MakeTrackName(trackId, NULL), "tref.hint");

    AddTrackReference(MakeTrackName(trackId, "tref.hint"), refTrackId);

    AddDescendantAtoms(MakeTrackName(trackId, NULL), "udta.hnti.sdp ");

    AddDescendantAtoms(MakeTrackName(trackId, NULL), "udta.hinf");

    return trackId;
}

void MP4File::DeleteTrack(MP4TrackId trackId)
{
    ProtectWriteOperation("MP4DeleteTrack");

    u_int32_t trakIndex = FindTrakAtomIndex(trackId);
    u_int16_t trackIndex = FindTrackIndex(trackId);
    MP4Track* pTrack = m_pTracks[trackIndex];

    MP4Atom* pTrakAtom = pTrack->GetTrakAtom();
    ASSERT(pTrakAtom);

    MP4Atom* pMoovAtom = FindAtom("moov");
    ASSERT(pMoovAtom);

    RemoveTrackFromIod(trackId);
    RemoveTrackFromOd(trackId);

    if (trackId == m_odTrackId) {
        m_odTrackId = 0;
    }

    pMoovAtom->DeleteChildAtom(pTrakAtom);

    m_trakIds.Delete(trakIndex);

    m_pTracks.Delete(trackIndex);

    delete pTrack;
    delete pTrakAtom;
}

u_int32_t MP4File::GetNumberOfTracks(const char* type, u_int8_t subType)
{
    if (type == NULL) {
        return m_pTracks.Size();
    }

    u_int32_t typeSeen = 0;
    const char* normType = MP4Track::NormalizeTrackType(type);

    for (u_int32_t i = 0; i < m_pTracks.Size(); i++) {
        if (!strcmp(normType, m_pTracks[i]->GetType())) {
            if (subType) {
                if (normType == MP4_AUDIO_TRACK_TYPE) {
                    if (subType != GetTrackEsdsObjectTypeId(m_pTracks[i]->GetId())) {
                        continue;
                    }
                } else if (normType == MP4_VIDEO_TRACK_TYPE) {
                    if (subType != GetTrackEsdsObjectTypeId(m_pTracks[i]->GetId())) {
                        continue;
                    }
                }
                // else unknown subtype, ignore it
            }
            typeSeen++;
        }
    }
    return typeSeen;
}

MP4TrackId MP4File::AllocTrackId()
{
    MP4TrackId trackId =
        GetIntegerProperty("moov.mvhd.nextTrackId");

    if (trackId <= 0xFFFF) {
        // check that nextTrackid is correct
        try {
            FindTrackIndex(trackId);
            // ERROR, this trackId is in use
        }
        catch (MP4Error* e) {
            // OK, this trackId is not in use, proceed
            delete e;
            SetIntegerProperty("moov.mvhd.nextTrackId", trackId + 1);
            return trackId;
        }
    }

    // we need to search for a track id
    for (trackId = 1; trackId <= 0xFFFF; trackId++) {
        try {
            FindTrackIndex(trackId);
            // KEEP LOOKING, this trackId is in use
        }
        catch (MP4Error* e) {
            // OK, this trackId is not in use, proceed
            delete e;
            return trackId;
        }
    }

    // extreme case where mp4 file has 2^16 tracks in it
    throw new MP4Error("too many existing tracks", "AddTrack");
    return MP4_INVALID_TRACK_ID;        // to keep MSVC happy
}

MP4TrackId MP4File::FindTrackId(u_int16_t trackIndex,
                const char* type, u_int8_t subType)
{
  if (type == NULL) {
    return m_pTracks[trackIndex]->GetId();
  }

  u_int32_t typeSeen = 0;
  const char* normType = MP4Track::NormalizeTrackType(type);

  for (u_int32_t i = 0; i < m_pTracks.Size(); i++) {
    if (!strcmp(normType, m_pTracks[i]->GetType())) {
      if (subType) {
    if (normType == MP4_AUDIO_TRACK_TYPE) {
      if (subType != GetTrackEsdsObjectTypeId(m_pTracks[i]->GetId())) {
        continue;
      }
    } else if (normType == MP4_VIDEO_TRACK_TYPE) {
      if (subType != GetTrackEsdsObjectTypeId(m_pTracks[i]->GetId())) {
        continue;
      }
    }
    // else unknown subtype, ignore it
      }

      if (trackIndex == typeSeen) {
    return m_pTracks[i]->GetId();
      }

      typeSeen++;
    }
  }

  throw new MP4Error("Track index doesn't exist - track %d type %s",
             "FindTrackId",
             trackIndex, type);
  return MP4_INVALID_TRACK_ID; // satisfy MS compiler
}

u_int16_t MP4File::FindTrackIndex(MP4TrackId trackId)
{
    for (u_int32_t i = 0; i < m_pTracks.Size() && i <= 0xFFFF; i++) {
        if (m_pTracks[i]->GetId() == trackId) {
            return (u_int16_t)i;
        }
    }

    throw new MP4Error("Track id %d doesn't exist", "FindTrackIndex", trackId);
    return (u_int16_t)-1; // satisfy MS compiler
}

u_int16_t MP4File::FindTrakAtomIndex(MP4TrackId trackId)
{
    if (trackId) {
        for (u_int32_t i = 0; i < m_trakIds.Size(); i++) {
            if (m_trakIds[i] == trackId) {
                return i;
            }
        }
    }

    throw new MP4Error("Track id %d doesn't exist", "FindTrakAtomIndex",
               trackId);
    return (u_int16_t)-1; // satisfy MS compiler
}

u_int32_t MP4File::GetSampleSize(MP4TrackId trackId, MP4SampleId sampleId)
{
    return m_pTracks[FindTrackIndex(trackId)]->GetSampleSize(sampleId);
}

u_int32_t MP4File::GetTrackMaxSampleSize(MP4TrackId trackId)
{
    return m_pTracks[FindTrackIndex(trackId)]->GetMaxSampleSize();
}

MP4SampleId MP4File::GetSampleIdFromTime(MP4TrackId trackId,
    MP4Timestamp when, bool wantSyncSample)
{
    return m_pTracks[FindTrackIndex(trackId)]->
        GetSampleIdFromTime(when, wantSyncSample);
}

MP4Timestamp MP4File::GetSampleTime(
    MP4TrackId trackId, MP4SampleId sampleId)
{
    MP4Timestamp timestamp;
    m_pTracks[FindTrackIndex(trackId)]->
        GetSampleTimes(sampleId, &timestamp, NULL);
    return timestamp;
}

MP4Duration MP4File::GetSampleDuration(
    MP4TrackId trackId, MP4SampleId sampleId)
{
    MP4Duration duration;
    m_pTracks[FindTrackIndex(trackId)]->
        GetSampleTimes(sampleId, NULL, &duration);
    return duration;
}

MP4Duration MP4File::GetSampleRenderingOffset(
    MP4TrackId trackId, MP4SampleId sampleId)
{
    return m_pTracks[FindTrackIndex(trackId)]->
        GetSampleRenderingOffset(sampleId);
}

bool MP4File::GetSampleSync(MP4TrackId trackId, MP4SampleId sampleId)
{
    return m_pTracks[FindTrackIndex(trackId)]->IsSyncSample(sampleId);
}

void MP4File::ReadSample(MP4TrackId trackId, MP4SampleId sampleId,
        u_int8_t** ppBytes, u_int32_t* pNumBytes,
        MP4Timestamp* pStartTime, MP4Duration* pDuration,
        MP4Duration* pRenderingOffset, bool* pIsSyncSample)
{
    m_pTracks[FindTrackIndex(trackId)]->
        ReadSample(sampleId, ppBytes, pNumBytes,
            pStartTime, pDuration, pRenderingOffset, pIsSyncSample);
}

void MP4File::WriteSample(MP4TrackId trackId,
        const u_int8_t* pBytes, u_int32_t numBytes,
        MP4Duration duration, MP4Duration renderingOffset, bool isSyncSample)
{
    ProtectWriteOperation("MP4WriteSample");

    m_pTracks[FindTrackIndex(trackId)]->
        WriteSample(pBytes, numBytes, duration, renderingOffset, isSyncSample);

    m_pModificationProperty->SetValue(MP4GetAbsTimestamp());
}

void MP4File::SetSampleRenderingOffset(MP4TrackId trackId,
    MP4SampleId sampleId, MP4Duration renderingOffset)
{
    ProtectWriteOperation("MP4SetSampleRenderingOffset");

    m_pTracks[FindTrackIndex(trackId)]->
        SetSampleRenderingOffset(sampleId, renderingOffset);

    m_pModificationProperty->SetValue(MP4GetAbsTimestamp());
}

char* MP4File::MakeTrackName(MP4TrackId trackId, const char* name)
{
    u_int16_t trakIndex = FindTrakAtomIndex(trackId);

    static char trakName[1024];
    if (name == NULL || name[0] == '\0') {
        snprintf(trakName, sizeof(trakName),
            "moov.trak[%u]", trakIndex);
    } else {
        snprintf(trakName, sizeof(trakName),
            "moov.trak[%u].%s", trakIndex, name);
    }
    return trakName;
}

u_int64_t MP4File::GetTrackIntegerProperty(MP4TrackId trackId, const char* name)
{
    return GetIntegerProperty(MakeTrackName(trackId, name));
}

void MP4File::SetTrackIntegerProperty(MP4TrackId trackId, const char* name,
    int64_t value)
{
    SetIntegerProperty(MakeTrackName(trackId, name), value);
}

float MP4File::GetTrackFloatProperty(MP4TrackId trackId, const char* name)
{
    return GetFloatProperty(MakeTrackName(trackId, name));
}

void MP4File::SetTrackFloatProperty(MP4TrackId trackId, const char* name,
    float value)
{
    SetFloatProperty(MakeTrackName(trackId, name), value);
}

const char* MP4File::GetTrackStringProperty(MP4TrackId trackId, const char* name)
{
    return GetStringProperty(MakeTrackName(trackId, name));
}

void MP4File::SetTrackStringProperty(MP4TrackId trackId, const char* name,
    const char* value)
{
    SetStringProperty(MakeTrackName(trackId, name), value);
}

void MP4File::GetTrackBytesProperty(MP4TrackId trackId, const char* name,
    u_int8_t** ppValue, u_int32_t* pValueSize)
{
    GetBytesProperty(MakeTrackName(trackId, name), ppValue, pValueSize);
}

void MP4File::SetTrackBytesProperty(MP4TrackId trackId, const char* name,
    const u_int8_t* pValue, u_int32_t valueSize)
{
    SetBytesProperty(MakeTrackName(trackId, name), pValue, valueSize);
}


// file level convenience functions

MP4Duration MP4File::GetDuration()
{
    return m_pDurationProperty->GetValue();
}

void MP4File::SetDuration(MP4Duration value)
{
    m_pDurationProperty->SetValue(value);
}

u_int32_t MP4File::GetTimeScale()
{
    return m_pTimeScaleProperty->GetValue();
}

void MP4File::SetTimeScale(u_int32_t value)
{
    if (value == 0) {
        throw new MP4Error("invalid value", "SetTimeScale");
    }
    m_pTimeScaleProperty->SetValue(value);
}

u_int8_t MP4File::GetODProfileLevel()
{
    return GetIntegerProperty("moov.iods.ODProfileLevelId");
}

void MP4File::SetODProfileLevel(u_int8_t value)
{
    SetIntegerProperty("moov.iods.ODProfileLevelId", value);
}

u_int8_t MP4File::GetSceneProfileLevel()
{
    return GetIntegerProperty("moov.iods.sceneProfileLevelId");
}

void MP4File::SetSceneProfileLevel(u_int8_t value)
{
    SetIntegerProperty("moov.iods.sceneProfileLevelId", value);
}

u_int8_t MP4File::GetVideoProfileLevel()
{
    return GetIntegerProperty("moov.iods.visualProfileLevelId");
}

void MP4File::SetVideoProfileLevel(u_int8_t value)
{
    SetIntegerProperty("moov.iods.visualProfileLevelId", value);
}

u_int8_t MP4File::GetAudioProfileLevel()
{
    return GetIntegerProperty("moov.iods.audioProfileLevelId");
}

void MP4File::SetAudioProfileLevel(u_int8_t value)
{
    SetIntegerProperty("moov.iods.audioProfileLevelId", value);
}

u_int8_t MP4File::GetGraphicsProfileLevel()
{
    return GetIntegerProperty("moov.iods.graphicsProfileLevelId");
}

void MP4File::SetGraphicsProfileLevel(u_int8_t value)
{
    SetIntegerProperty("moov.iods.graphicsProfileLevelId", value);
}

const char* MP4File::GetSessionSdp()
{
    return GetStringProperty("moov.udta.hnti.rtp .sdpText");
}

void MP4File::SetSessionSdp(const char* sdpString)
{
    AddDescendantAtoms("moov", "udta.hnti.rtp ");

    SetStringProperty("moov.udta.hnti.rtp .sdpText", sdpString);
}

void MP4File::AppendSessionSdp(const char* sdpFragment)
{
    const char* oldSdpString = NULL;
    try {
        oldSdpString = GetSessionSdp();
    }
    catch (MP4Error* e) {
        delete e;
        SetSessionSdp(sdpFragment);
        return;
    }

    char* newSdpString =
        (char*)MP4Malloc(strlen(oldSdpString) + strlen(sdpFragment) + 1);
    strcpy(newSdpString, oldSdpString);
    strcat(newSdpString, sdpFragment);

⌨️ 快捷键说明

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