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

📄 rtphint.cpp

📁 6410BSP1
💻 CPP
📖 第 1 页 / 共 3 页
字号:
    }    if (include_mpeg4_esid) {      sprintf(sdpBuf + buflen,           "a=mpeg4-esid:%u\015\012",          m_pRefTrack->GetId());    }    MP4StringProperty* pSdpProperty = NULL;    m_pTrakAtom->FindProperty("trak.udta.hnti.sdp .sdpText",        (MP4Property**)&pSdpProperty);    ASSERT(pSdpProperty);    pSdpProperty->SetValue(sdpBuf);    // cleanup    MP4Free(rtpMapBuf);    MP4Free(sdpBuf);}void MP4RtpHintTrack::AddHint(bool isBFrame, u_int32_t timestampOffset){    // on first hint, need to lookup the reference track    if (m_writeHintId == MP4_INVALID_SAMPLE_ID) {        InitRefTrack();        InitStats();    }    if (m_pWriteHint) {        throw new MP4Error("unwritten hint is still pending", "MP4AddRtpHint");    }    m_pWriteHint = new MP4RtpHint(this);    m_pWriteHint->SetBFrame(isBFrame);    m_pWriteHint->SetTimestampOffset(timestampOffset);    m_bytesThisHint = 0;    m_writeHintId++;}void MP4RtpHintTrack::AddPacket(bool setMbit, int32_t transmitOffset){    if (m_pWriteHint == NULL) {        throw new MP4Error("no hint pending", "MP4RtpAddPacket");    }    MP4RtpPacket* pPacket = m_pWriteHint->AddPacket();    ASSERT(m_pPayloadNumberProperty);    pPacket->Set(        m_pPayloadNumberProperty->GetValue(),         m_writePacketId++,         setMbit);    pPacket->SetTransmitOffset(transmitOffset);    m_bytesThisHint += 12;    if (m_bytesThisPacket > m_pPmax->GetValue()) {        m_pPmax->SetValue(m_bytesThisPacket);    }    m_bytesThisPacket = 12;    m_pNump->IncrementValue();    m_pTrpy->IncrementValue(12); // RTP packet header size}void MP4RtpHintTrack::AddImmediateData(    const u_int8_t* pBytes,    u_int32_t numBytes){    if (m_pWriteHint == NULL) {        throw new MP4Error("no hint pending", "MP4RtpAddImmediateData");    }    MP4RtpPacket* pPacket = m_pWriteHint->GetCurrentPacket();    if (pPacket == NULL) {        throw new MP4Error("no packet pending", "MP4RtpAddImmediateData");    }    if (pBytes == NULL || numBytes == 0) {        throw new MP4Error("no data",            "AddImmediateData");    }    if (numBytes > 14) {        throw new MP4Error("data size is larger than 14 bytes",            "AddImmediateData");    }    MP4RtpImmediateData* pData = new MP4RtpImmediateData(pPacket);    pData->Set(pBytes, numBytes);    pPacket->AddData(pData);    m_bytesThisHint += numBytes;    m_bytesThisPacket += numBytes;    m_pDimm->IncrementValue(numBytes);    m_pTpyl->IncrementValue(numBytes);    m_pTrpy->IncrementValue(numBytes);}void MP4RtpHintTrack::AddSampleData(    MP4SampleId sampleId,    u_int32_t dataOffset,    u_int32_t dataLength){    if (m_pWriteHint == NULL) {        throw new MP4Error("no hint pending", "MP4RtpAddSampleData");    }    MP4RtpPacket* pPacket = m_pWriteHint->GetCurrentPacket();    if (pPacket == NULL) {        throw new MP4Error("no packet pending", "MP4RtpAddSampleData");    }    MP4RtpSampleData* pData = new MP4RtpSampleData(pPacket);    pData->SetReferenceSample(sampleId, dataOffset, dataLength);    pPacket->AddData(pData);    m_bytesThisHint += dataLength;    m_bytesThisPacket += dataLength;    m_pDmed->IncrementValue(dataLength);    m_pTpyl->IncrementValue(dataLength);    m_pTrpy->IncrementValue(dataLength);}void MP4RtpHintTrack::AddESConfigurationPacket(){    if (m_pWriteHint == NULL) {        throw new MP4Error("no hint pending",             "MP4RtpAddESConfigurationPacket");    }    u_int8_t* pConfig = NULL;    u_int32_t configSize = 0;    m_pFile->GetTrackESConfiguration(m_pRefTrack->GetId(),        &pConfig, &configSize);    if (pConfig == NULL) {        return;    }    ASSERT(m_pMaxPacketSizeProperty);    if (configSize > m_pMaxPacketSizeProperty->GetValue()) {        throw new MP4Error("ES configuration is too large for RTP payload",            "MP4RtpAddESConfigurationPacket");    }    AddPacket(false);    MP4RtpPacket* pPacket = m_pWriteHint->GetCurrentPacket();    ASSERT(pPacket);        // This is ugly!    // To get the ES configuration data somewhere known    // we create a sample data reference that points to     // this hint track (not the media track)    // and this sample of the hint track     // the offset into this sample is filled in during the write process    MP4RtpSampleData* pData = new MP4RtpSampleData(pPacket);    pData->SetEmbeddedImmediate(m_writeSampleId, pConfig, configSize);    pPacket->AddData(pData);    m_bytesThisHint += configSize;    m_bytesThisPacket += configSize;    m_pTpyl->IncrementValue(configSize);    m_pTrpy->IncrementValue(configSize);}void MP4RtpHintTrack::WriteHint(MP4Duration duration, bool isSyncSample){    if (m_pWriteHint == NULL) {        throw new MP4Error("no hint pending", "MP4WriteRtpHint");    }    u_int8_t* pBytes;    u_int64_t numBytes;    m_pFile->EnableMemoryBuffer();    m_pWriteHint->Write(m_pFile);    m_pFile->DisableMemoryBuffer(&pBytes, &numBytes);    WriteSample(pBytes, numBytes, duration, 0, isSyncSample);    MP4Free(pBytes);    // update statistics    if (m_bytesThisPacket > m_pPmax->GetValue()) {        m_pPmax->SetValue(m_bytesThisPacket);    }    if (duration > m_pDmax->GetValue()) {        m_pDmax->SetValue(duration);    }    MP4Timestamp startTime;    GetSampleTimes(m_writeHintId, &startTime, NULL);    if (startTime < m_thisSec + GetTimeScale()) {        m_bytesThisSec += m_bytesThisHint;    } else {        if (m_bytesThisSec > m_pMaxr->GetValue()) {            m_pMaxr->SetValue(m_bytesThisSec);        }        m_thisSec = startTime - (startTime % GetTimeScale());        m_bytesThisSec = m_bytesThisHint;    }    // cleanup    delete m_pWriteHint;    m_pWriteHint = NULL;}void MP4RtpHintTrack::FinishWrite(){    if (m_writeHintId != MP4_INVALID_SAMPLE_ID) {        m_pMaxPdu->SetValue(m_pPmax->GetValue());        if (m_pNump->GetValue()) {            m_pAvgPdu->SetValue(m_pTrpy->GetValue() / m_pNump->GetValue());        }        m_pMaxBitRate->SetValue(m_pMaxr->GetValue() * 8);        if (GetDuration()) {            m_pAvgBitRate->SetValue(                m_pTrpy->GetValue() * 8 * GetTimeScale() / GetDuration());        }    }    MP4Track::FinishWrite();}void MP4RtpHintTrack::InitStats(){    MP4Atom* pHinfAtom = m_pTrakAtom->FindAtom("trak.udta.hinf");    ASSERT(pHinfAtom);    pHinfAtom->FindProperty("hinf.trpy.bytes", (MP4Property**)&m_pTrpy);     pHinfAtom->FindProperty("hinf.nump.packets", (MP4Property**)&m_pNump);     pHinfAtom->FindProperty("hinf.tpyl.bytes", (MP4Property**)&m_pTpyl);     pHinfAtom->FindProperty("hinf.maxr.bytes", (MP4Property**)&m_pMaxr);     pHinfAtom->FindProperty("hinf.dmed.bytes", (MP4Property**)&m_pDmed);     pHinfAtom->FindProperty("hinf.dimm.bytes", (MP4Property**)&m_pDimm);     pHinfAtom->FindProperty("hinf.pmax.bytes", (MP4Property**)&m_pPmax);     pHinfAtom->FindProperty("hinf.dmax.milliSecs", (MP4Property**)&m_pDmax);     MP4Atom* pHmhdAtom = m_pTrakAtom->FindAtom("trak.mdia.minf.hmhd");    ASSERT(pHmhdAtom);    pHmhdAtom->FindProperty("hmhd.maxPduSize", (MP4Property**)&m_pMaxPdu);     pHmhdAtom->FindProperty("hmhd.avgPduSize", (MP4Property**)&m_pAvgPdu);     pHmhdAtom->FindProperty("hmhd.maxBitRate", (MP4Property**)&m_pMaxBitRate);     pHmhdAtom->FindProperty("hmhd.avgBitRate", (MP4Property**)&m_pAvgBitRate);     MP4Integer32Property* pMaxrPeriod = NULL;    pHinfAtom->FindProperty("hinf.maxr.granularity",         (MP4Property**)&pMaxrPeriod);     if (pMaxrPeriod) {        pMaxrPeriod->SetValue(1000);    // 1 second    }}MP4RtpHint::MP4RtpHint(MP4RtpHintTrack* pTrack){    m_pTrack = pTrack;    AddProperty( /* 0 */        new MP4Integer16Property("packetCount"));    AddProperty( /* 1 */        new MP4Integer16Property("reserved"));}MP4RtpHint::~MP4RtpHint(){    for (u_int32_t i = 0; i < m_rtpPackets.Size(); i++) {        delete m_rtpPackets[i];    }}MP4RtpPacket* MP4RtpHint::AddPacket() {    MP4RtpPacket* pPacket = new MP4RtpPacket(this);    m_rtpPackets.Add(pPacket);    // packetCount property    ((MP4Integer16Property*)m_pProperties[0])->IncrementValue();    pPacket->SetBFrame(m_isBFrame);    pPacket->SetTimestampOffset(m_timestampOffset);    return pPacket;}void MP4RtpHint::Read(MP4File* pFile){    // call base class Read for required properties    MP4Container::Read(pFile);    u_int16_t numPackets =        ((MP4Integer16Property*)m_pProperties[0])->GetValue();    for (u_int16_t i = 0; i < numPackets; i++) {        MP4RtpPacket* pPacket = new MP4RtpPacket(this);        m_rtpPackets.Add(pPacket);        pPacket->Read(pFile);    }    VERBOSE_READ_HINT(pFile->GetVerbosity(),        printf("ReadHint:\n"); Dump(stdout, 10, false););}void MP4RtpHint::Write(MP4File* pFile){    u_int64_t hintStartPos = pFile->GetPosition();    MP4Container::Write(pFile);    u_int64_t packetStartPos = pFile->GetPosition();    u_int32_t i;    // first write out packet (and data) entries    for (i = 0; i < m_rtpPackets.Size(); i++) {        m_rtpPackets[i]->Write(pFile);    }    // now let packets write their extra data into the hint sample    for (i = 0; i < m_rtpPackets.Size(); i++) {        m_rtpPackets[i]->WriteEmbeddedData(pFile, hintStartPos);    }    u_int64_t endPos = pFile->GetPosition();    pFile->SetPosition(packetStartPos);    // finally rewrite the packet and data entries    // which now contain the correct offsets for the embedded data    for (i = 0; i < m_rtpPackets.Size(); i++) {        m_rtpPackets[i]->Write(pFile);    }    pFile->SetPosition(endPos);    VERBOSE_WRITE_HINT(pFile->GetVerbosity(),        printf("WriteRtpHint:\n"); Dump(stdout, 14, false));}void MP4RtpHint::Dump(FILE* pFile, u_int8_t indent, bool dumpImplicits){    MP4Container::Dump(pFile, indent, dumpImplicits);    for (u_int32_t i = 0; i < m_rtpPackets.Size(); i++) {        Indent(pFile, indent);        fprintf(pFile, "RtpPacket: %u\n", i);        m_rtpPackets[i]->Dump(pFile, indent + 1, dumpImplicits);    }}MP4RtpPacket::MP4RtpPacket(MP4RtpHint* pHint){    m_pHint = pHint;    AddProperty( /* 0 */        new MP4Integer32Property("relativeXmitTime"));    AddProperty( /* 1 */        new MP4BitfieldProperty("reserved1", 2));    AddProperty( /* 2 */        new MP4BitfieldProperty("Pbit", 1));    AddProperty( /* 3 */        new MP4BitfieldProperty("Xbit", 1));    AddProperty( /* 4 */        new MP4BitfieldProperty("reserved2", 4));    AddProperty( /* 5 */        new MP4BitfieldProperty("Mbit", 1));    AddProperty( /* 6 */        new MP4BitfieldProperty("payloadType", 7));    AddProperty( /* 7  */        new MP4Integer16Property("sequenceNumber"));    AddProperty( /* 8 */        new MP4BitfieldProperty("reserved3", 13));    AddProperty( /* 9 */        new MP4BitfieldProperty("extraFlag", 1));    AddProperty( /* 10 */        new MP4BitfieldProperty("bFrameFlag", 1));    AddProperty( /* 11 */        new MP4BitfieldProperty("repeatFlag", 1));    AddProperty( /* 12 */        new MP4Integer16Property("entryCount"));} MP4RtpPacket::~MP4RtpPacket(){    for (u_int32_t i = 0; i < m_rtpData.Size(); i++) {        delete m_rtpData[i];    }}void MP4RtpPacket::AddExtraProperties(){    AddProperty( /* 13 */        new MP4Integer32Property("extraInformationLength"));    // This is a bit of a hack, since the tlv entries are really defined     // as atoms but there is only one type defined now, rtpo, and getting     // our atom code hooked up here would be a major pain with little gain    AddProperty( /* 14 */        new MP4Integer32Property("tlvLength"));    AddProperty( /* 15 */        new MP4StringProperty("tlvType"));    AddProperty( /* 16 */        new MP4Integer32Property("timestampOffset"));    ((MP4Integer32Property*)m_pProperties[13])->SetValue(16);    ((MP4Integer32Property*)m_pProperties[14])->SetValue(12);    ((MP4StringProperty*)m_pProperties[15])->SetFixedLength(4);    ((MP4StringProperty*)m_pProperties[15])->SetValue("rtpo");}void MP4RtpPacket::Read(MP4File* pFile){    // call base class Read for required properties    MP4Container::Read(pFile);    // read extra info if present    // we only support the rtpo field!    if (((MP4BitfieldProperty*)m_pProperties[9])->GetValue() == 1) {        ReadExtra(pFile);    }    u_int16_t numDataEntries =        ((MP4Integer16Property*)m_pProperties[12])->GetValue();    // read data entries    for (u_int16_t i = 0; i < numDataEntries; i++) {        u_int8_t dataType;        pFile->PeekBytes(&dataType, 1);        MP4RtpData* pData;        switch (dataType) {        case 0:            pData = new MP4RtpNullData(this);            break;        case 1:            pData = new MP4RtpImmediateData(this);            break;        case 2:            pData = new MP4RtpSampleData(this);            break;        case 3:            pData = new MP4RtpSampleDescriptionData(this);            break;        default:            throw new MP4Error("unknown packet data entry type",                "MP4ReadHint");

⌨️ 快捷键说明

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