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

📄 rtphint.cpp

📁 完整的RTP RTSP代码库
💻 CPP
📖 第 1 页 / 共 3 页
字号:
{	// 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);	(void)pHinfAtom->FindProperty("hinf.trpy.bytes", (MP4Property**)&m_pTrpy); 	(void)pHinfAtom->FindProperty("hinf.nump.packets", (MP4Property**)&m_pNump); 	(void)pHinfAtom->FindProperty("hinf.tpyl.bytes", (MP4Property**)&m_pTpyl); 	(void)pHinfAtom->FindProperty("hinf.maxr.bytes", (MP4Property**)&m_pMaxr); 	(void)pHinfAtom->FindProperty("hinf.dmed.bytes", (MP4Property**)&m_pDmed); 	(void)pHinfAtom->FindProperty("hinf.dimm.bytes", (MP4Property**)&m_pDimm); 	(void)pHinfAtom->FindProperty("hinf.pmax.bytes", (MP4Property**)&m_pPmax); 	(void)pHinfAtom->FindProperty("hinf.dmax.milliSecs", (MP4Property**)&m_pDmax); 	MP4Atom* pHmhdAtom = m_pTrakAtom->FindAtom("trak.mdia.minf.hmhd");	ASSERT(pHmhdAtom);	(void)pHmhdAtom->FindProperty("hmhd.maxPduSize", (MP4Property**)&m_pMaxPdu); 	(void)pHmhdAtom->FindProperty("hmhd.avgPduSize", (MP4Property**)&m_pAvgPdu); 	(void)pHmhdAtom->FindProperty("hmhd.maxBitRate", (MP4Property**)&m_pMaxBitRate); 	(void)pHmhdAtom->FindProperty("hmhd.avgBitRate", (MP4Property**)&m_pAvgBitRate); 	MP4Integer32Property* pMaxrPeriod = NULL;	(void)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");		}		m_rtpData.Add(pData);		// read data entry's properties		pData->Read(pFile);	}}

⌨️ 快捷键说明

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