📄 rtphint.cpp
字号:
} m_rtpData.Add(pData); // read data entry's properties pData->Read(pFile); }}void MP4RtpPacket::ReadExtra(MP4File* pFile){ AddExtraProperties(); int32_t extraLength = (int32_t)pFile->ReadUInt32(); if (extraLength < 4) { throw new MP4Error("bad packet extra info length", "MP4RtpPacket::ReadExtra"); } extraLength -= 4; while (extraLength > 0) { u_int32_t entryLength = pFile->ReadUInt32(); u_int32_t entryTag = pFile->ReadUInt32(); if (entryLength < 8) { throw new MP4Error("bad packet extra info entry length", "MP4RtpPacket::ReadExtra"); } if (entryTag == STRTOINT32("rtpo") && entryLength == 12) { // read the rtp timestamp offset m_pProperties[16]->Read(pFile); } else { // ignore it, LATER carry it along pFile->SetPosition(pFile->GetPosition() + entryLength - 8); } extraLength -= entryLength; } if (extraLength < 0) { throw new MP4Error("invalid packet extra info length", "MP4RtpPacket::ReadExtra"); }}void MP4RtpPacket::Set(u_int8_t payloadNumber, u_int32_t packetId, bool setMbit){ ((MP4BitfieldProperty*)m_pProperties[5])->SetValue(setMbit); ((MP4BitfieldProperty*)m_pProperties[6])->SetValue(payloadNumber); ((MP4Integer16Property*)m_pProperties[7])->SetValue(packetId);}int32_t MP4RtpPacket::GetTransmitOffset(){ return ((MP4Integer32Property*)m_pProperties[0])->GetValue();}void MP4RtpPacket::SetTransmitOffset(int32_t transmitOffset){ ((MP4Integer32Property*)m_pProperties[0])->SetValue(transmitOffset);}bool MP4RtpPacket::GetPBit(){ return ((MP4BitfieldProperty*)m_pProperties[2])->GetValue();}bool MP4RtpPacket::GetXBit(){ return ((MP4BitfieldProperty*)m_pProperties[3])->GetValue();}bool MP4RtpPacket::GetMBit(){ return ((MP4BitfieldProperty*)m_pProperties[5])->GetValue();}u_int8_t MP4RtpPacket::GetPayload(){ return ((MP4BitfieldProperty*)m_pProperties[6])->GetValue();}u_int16_t MP4RtpPacket::GetSequenceNumber(){ return ((MP4Integer16Property*)m_pProperties[7])->GetValue();}bool MP4RtpPacket::IsBFrame(){ return ((MP4BitfieldProperty*)m_pProperties[10])->GetValue();}void MP4RtpPacket::SetBFrame(bool isBFrame){ ((MP4BitfieldProperty*)m_pProperties[10])->SetValue(isBFrame);}void MP4RtpPacket::SetTimestampOffset(u_int32_t timestampOffset){ if (timestampOffset == 0) { return; } ASSERT(((MP4BitfieldProperty*)m_pProperties[9])->GetValue() == 0); // set X bit ((MP4BitfieldProperty*)m_pProperties[9])->SetValue(1); AddExtraProperties(); ((MP4Integer32Property*)m_pProperties[16])->SetValue(timestampOffset);}void MP4RtpPacket::AddData(MP4RtpData* pData){ m_rtpData.Add(pData); // increment entry count property ((MP4Integer16Property*)m_pProperties[12])->IncrementValue();}u_int32_t MP4RtpPacket::GetDataSize(){ u_int32_t totalDataSize = 0; for (u_int32_t i = 0; i < m_rtpData.Size(); i++) { totalDataSize += m_rtpData[i]->GetDataSize(); } return totalDataSize;}void MP4RtpPacket::GetData(u_int8_t* pDest){ for (u_int32_t i = 0; i < m_rtpData.Size(); i++) { m_rtpData[i]->GetData(pDest); pDest += m_rtpData[i]->GetDataSize(); }}void MP4RtpPacket::Write(MP4File* pFile){ MP4Container::Write(pFile); for (u_int32_t i = 0; i < m_rtpData.Size(); i++) { m_rtpData[i]->Write(pFile); }}void MP4RtpPacket::WriteEmbeddedData(MP4File* pFile, u_int64_t startPos){ for (u_int32_t i = 0; i < m_rtpData.Size(); i++) { m_rtpData[i]->WriteEmbeddedData(pFile, startPos); }}void MP4RtpPacket::Dump(FILE* pFile, u_int8_t indent, bool dumpImplicits){ MP4Container::Dump(pFile, indent, dumpImplicits); for (u_int32_t i = 0; i < m_rtpData.Size(); i++) { Indent(pFile, indent); fprintf(pFile, "RtpData: %u\n", i); m_rtpData[i]->Dump(pFile, indent + 1, dumpImplicits); }}MP4RtpData::MP4RtpData(MP4RtpPacket* pPacket){ m_pPacket = pPacket; AddProperty( /* 0 */ new MP4Integer8Property("type"));}MP4Track* MP4RtpData::FindTrackFromRefIndex(u_int8_t refIndex){ MP4Track* pTrack; if (refIndex == (u_int8_t)-1) { // ourselves pTrack = GetPacket()->GetHint()->GetTrack(); } else if (refIndex == 0) { // our reference track pTrack = GetPacket()->GetHint()->GetTrack()->GetRefTrack(); } else { // some other track MP4RtpHintTrack* pHintTrack = GetPacket()->GetHint()->GetTrack(); MP4Atom* pTrakAtom = pHintTrack->GetTrakAtom(); ASSERT(pTrakAtom); MP4Integer32Property* pTrackIdProperty = NULL; pTrakAtom->FindProperty( "trak.tref.hint.entries", (MP4Property**)&pTrackIdProperty); ASSERT(pTrackIdProperty); u_int32_t refTrackId = pTrackIdProperty->GetValue(refIndex - 1); pTrack = pHintTrack->GetFile()->GetTrack(refTrackId); } return pTrack;}MP4RtpNullData::MP4RtpNullData(MP4RtpPacket* pPacket) : MP4RtpData(pPacket){ ((MP4Integer8Property*)m_pProperties[0])->SetValue(0); AddProperty( /* 1 */ new MP4BytesProperty("pad", 15)); ((MP4BytesProperty*)m_pProperties[1])->SetFixedSize(15);}MP4RtpImmediateData::MP4RtpImmediateData(MP4RtpPacket* pPacket) : MP4RtpData(pPacket){ ((MP4Integer8Property*)m_pProperties[0])->SetValue(1); AddProperty( /* 1 */ new MP4Integer8Property("count")); AddProperty( /* 2 */ new MP4BytesProperty("data", 14)); ((MP4BytesProperty*)m_pProperties[2])->SetFixedSize(14);}void MP4RtpImmediateData::Set(const u_int8_t* pBytes, u_int8_t numBytes){ ((MP4Integer8Property*)m_pProperties[1])->SetValue(numBytes); ((MP4BytesProperty*)m_pProperties[2])->SetValue(pBytes, numBytes);}u_int16_t MP4RtpImmediateData::GetDataSize(){ return ((MP4Integer8Property*)m_pProperties[1])->GetValue();}void MP4RtpImmediateData::GetData(u_int8_t* pDest){ u_int8_t* pValue; u_int32_t valueSize; ((MP4BytesProperty*)m_pProperties[2])->GetValue(&pValue, &valueSize); memcpy(pDest, pValue, GetDataSize()); MP4Free(pValue);}MP4RtpSampleData::MP4RtpSampleData(MP4RtpPacket* pPacket) : MP4RtpData(pPacket){ ((MP4Integer8Property*)m_pProperties[0])->SetValue(2); AddProperty( /* 1 */ new MP4Integer8Property("trackRefIndex")); AddProperty( /* 2 */ new MP4Integer16Property("length")); AddProperty( /* 3 */ new MP4Integer32Property("sampleNumber")); AddProperty( /* 4 */ new MP4Integer32Property("sampleOffset")); AddProperty( /* 5 */ new MP4Integer16Property("bytesPerBlock")); AddProperty( /* 6 */ new MP4Integer16Property("samplesPerBlock")); ((MP4Integer16Property*)m_pProperties[5])->SetValue(1); ((MP4Integer16Property*)m_pProperties[6])->SetValue(1); m_pRefData = NULL; m_pRefTrack = NULL; m_refSampleId = MP4_INVALID_SAMPLE_ID; m_refSampleOffset = 0;}void MP4RtpSampleData::SetEmbeddedImmediate(MP4SampleId sampleId, u_int8_t* pData, u_int16_t dataLength){ ((MP4Integer8Property*)m_pProperties[1])->SetValue((u_int8_t)-1); ((MP4Integer16Property*)m_pProperties[2])->SetValue(dataLength); ((MP4Integer32Property*)m_pProperties[3])->SetValue(sampleId); ((MP4Integer32Property*)m_pProperties[4])->SetValue(0); CHECK_AND_FREE(m_pRefData); m_pRefData = pData;}void MP4RtpSampleData::SetReferenceSample( MP4SampleId refSampleId, u_int32_t refSampleOffset, u_int16_t sampleLength){ ((MP4Integer8Property*)m_pProperties[1])->SetValue(0); ((MP4Integer16Property*)m_pProperties[2])->SetValue(sampleLength); ((MP4Integer32Property*)m_pProperties[3])->SetValue(refSampleId); ((MP4Integer32Property*)m_pProperties[4])->SetValue(refSampleOffset);}void MP4RtpSampleData::SetEmbeddedSample( MP4SampleId sampleId, MP4Track* pRefTrack, MP4SampleId refSampleId, u_int32_t refSampleOffset, u_int16_t sampleLength){ ((MP4Integer8Property*)m_pProperties[1])->SetValue((u_int8_t)-1); ((MP4Integer16Property*)m_pProperties[2])->SetValue(sampleLength); ((MP4Integer32Property*)m_pProperties[3])->SetValue(sampleId); ((MP4Integer32Property*)m_pProperties[4])->SetValue(0); m_pRefTrack = pRefTrack; m_refSampleId = refSampleId; m_refSampleOffset = refSampleOffset;}u_int16_t MP4RtpSampleData::GetDataSize(){ return ((MP4Integer16Property*)m_pProperties[2])->GetValue();}void MP4RtpSampleData::GetData(u_int8_t* pDest){ u_int8_t trackRefIndex = ((MP4Integer8Property*)m_pProperties[1])->GetValue(); MP4Track* pSampleTrack = FindTrackFromRefIndex(trackRefIndex); pSampleTrack->ReadSampleFragment( ((MP4Integer32Property*)m_pProperties[3])->GetValue(), // sampleId ((MP4Integer32Property*)m_pProperties[4])->GetValue(), // sampleOffset ((MP4Integer16Property*)m_pProperties[2])->GetValue(), // sampleLength pDest);}void MP4RtpSampleData::WriteEmbeddedData(MP4File* pFile, u_int64_t startPos){ // if not using embedded data, nothing to do if (((MP4Integer8Property*)m_pProperties[1])->GetValue() != (u_int8_t)-1) { return; } // figure out the offset within this hint sample for this embedded data u_int64_t offset = pFile->GetPosition() - startPos; ASSERT(offset <= 0xFFFFFFFF); ((MP4Integer32Property*)m_pProperties[4])->SetValue((u_int32_t)offset); u_int16_t length = ((MP4Integer16Property*)m_pProperties[2])->GetValue(); if (m_pRefData) { pFile->WriteBytes(m_pRefData, length); return; } if (m_refSampleId != MP4_INVALID_SAMPLE_ID) { u_int8_t* pSample = NULL; u_int32_t sampleSize = 0; ASSERT(m_pRefTrack); m_pRefTrack->ReadSample(m_refSampleId, &pSample, &sampleSize); ASSERT(m_refSampleOffset + length <= sampleSize); pFile->WriteBytes(&pSample[m_refSampleOffset], length); MP4Free(pSample); return; }}MP4RtpSampleDescriptionData::MP4RtpSampleDescriptionData(MP4RtpPacket* pPacket) : MP4RtpData(pPacket){ ((MP4Integer8Property*)m_pProperties[0])->SetValue(3); AddProperty( /* 1 */ new MP4Integer8Property("trackRefIndex")); AddProperty( /* 2 */ new MP4Integer16Property("length")); AddProperty( /* 3 */ new MP4Integer32Property("sampleDescriptionIndex")); AddProperty( /* 4 */ new MP4Integer32Property("sampleDescriptionOffset")); AddProperty( /* 5 */ new MP4Integer32Property("reserved"));}void MP4RtpSampleDescriptionData::Set(u_int32_t sampleDescrIndex, u_int32_t offset, u_int16_t length){ ((MP4Integer16Property*)m_pProperties[2])->SetValue(length); ((MP4Integer32Property*)m_pProperties[3])->SetValue(sampleDescrIndex); ((MP4Integer32Property*)m_pProperties[4])->SetValue(offset);}u_int16_t MP4RtpSampleDescriptionData::GetDataSize(){ return ((MP4Integer16Property*)m_pProperties[2])->GetValue();}void MP4RtpSampleDescriptionData::GetData(u_int8_t* pDest){ // we start with the index into our track references u_int8_t trackRefIndex = ((MP4Integer8Property*)m_pProperties[1])->GetValue(); // from which we can find the track structure MP4Track* pSampleTrack = FindTrackFromRefIndex(trackRefIndex); // next find the desired atom in the track's sample description table u_int32_t sampleDescrIndex = ((MP4Integer32Property*)m_pProperties[3])->GetValue(); MP4Atom* pTrakAtom = pSampleTrack->GetTrakAtom(); char sdName[64]; sprintf(sdName, "trak.mdia.minf.stbl.stsd.*[%u]", sampleDescrIndex); MP4Atom* pSdAtom = pTrakAtom->FindAtom(sdName); // bad reference if (pSdAtom == NULL) { throw new MP4Error("invalid sample description index", "MP4RtpSampleDescriptionData::GetData"); } // check validity of the upcoming copy u_int16_t length = ((MP4Integer16Property*)m_pProperties[2])->GetValue(); u_int32_t offset = ((MP4Integer32Property*)m_pProperties[4])->GetValue(); if (offset + length > pSdAtom->GetSize()) { throw new MP4Error("offset and/or length are too large", "MP4RtpSampleDescriptionData::GetData"); } // now we use the raw file to get the desired bytes MP4File* pFile = GetPacket()->GetHint()->GetTrack()->GetFile(); u_int64_t orgPos = pFile->GetPosition(); // It's not entirely clear from the spec whether the offset is from // the start of the sample descirption atom, or the start of the atom's // data. I believe it is the former, but the commented out code will // realize the latter interpretation if I turn out to be wrong. u_int64_t dataPos = pSdAtom->GetStart(); //u_int64_t dataPos = pSdAtom->GetEnd() - pSdAtom->GetSize(); pFile->SetPosition(dataPos + offset); pFile->ReadBytes(pDest, length); pFile->SetPosition(orgPos);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -